2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2018 - 2020 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 ,  the  SerenityOS  developers . 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 13:34:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "Editor.h" 
  
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/CharacterTypes.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/Debug.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/FileStream.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-08-17 21:08:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/GenericLexer.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/JsonObject.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/MemoryStream.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-08-31 22:04:32 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/ScopeGuard.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-03-12 17:29:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/ScopedValueRollback.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-04-01 11:24:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/StringBuilder.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/Utf32View.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <AK/Utf8View.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-08-17 19:13:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibCore/ConfigFile.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibCore/Event.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibCore/EventLoop.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-10-25 23:25:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibCore/File.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibCore/Notifier.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-03-12 17:29:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <errno.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:09:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <signal.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <stdio.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <sys/ioctl.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-04-29 01:47:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <sys/select.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <sys/time.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <unistd.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-06 12:22:03 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								namespace  {  
						 
					
						
							
								
									
										
										
										
											2020-08-06 14:58:47 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								constexpr  u32  ctrl ( char  c )  {  return  c  &  0x3f ;  }  
						 
					
						
							
								
									
										
										
										
											2020-07-06 12:22:03 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 13:34:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								namespace  Line  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 19:13:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Configuration  Configuration : : from_config ( const  StringView &  libname )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Configuration  configuration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  config_file  =  Core : : ConfigFile : : get_for_lib ( libname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Read behaviour options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  refresh  =  config_file - > read_entry ( " behaviour " ,  " refresh " ,  " lazy " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  operation  =  config_file - > read_entry ( " behaviour " ,  " operation_mode " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-24 16:30:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  bracketed_paste  =  config_file - > read_bool_entry ( " behaviour " ,  " bracketed_paste " ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-17 21:41:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  default_text_editor  =  config_file - > read_entry ( " behaviour " ,  " default_text_editor " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 19:13:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-24 16:30:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Configuration : : Flags  flags  {  Configuration : : Flags : : None  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( bracketed_paste ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        flags  =  static_cast < Flags > ( flags  |  Configuration : : Flags : : BracketedPaste ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    configuration . set ( flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 19:13:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( refresh . equals_ignoring_case ( " lazy " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        configuration . set ( Configuration : : Lazy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( refresh . equals_ignoring_case ( " eager " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        configuration . set ( Configuration : : Eager ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( operation . equals_ignoring_case ( " full " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        configuration . set ( Configuration : : OperationMode : : Full ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( operation . equals_ignoring_case ( " noescapesequences " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        configuration . set ( Configuration : : OperationMode : : NoEscapeSequences ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( operation . equals_ignoring_case ( " noninteractive " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        configuration . set ( Configuration : : OperationMode : : NonInteractive ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        configuration . set ( Configuration : : OperationMode : : Unset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-17 21:41:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! default_text_editor . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        configuration . set ( DefaultTextEditor  {  move ( default_text_editor )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        configuration . set ( DefaultTextEditor  {  " /bin/TextEditor "  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 21:08:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Read keybinds.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  binding_key  :  config_file - > keys ( " keybinds " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        GenericLexer  key_lexer ( binding_key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  has_ctrl  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  alt  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 10:07:00 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  escape  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Vector < Key >  keys ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 21:08:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        while  ( ! key_lexer . is_eof ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 10:07:00 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            unsigned  key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( escape )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                key  =  key_lexer . consume_escaped_character ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                escape  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( key_lexer . next_is ( " alt+ " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    alt  =  key_lexer . consume_specific ( " alt+ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( key_lexer . next_is ( " ^[ " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    alt  =  key_lexer . consume_specific ( " ^[ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( key_lexer . next_is ( " ^ " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    has_ctrl  =  key_lexer . consume_specific ( " ^ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( key_lexer . next_is ( " ctrl+ " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    has_ctrl  =  key_lexer . consume_specific ( " ctrl+ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( key_lexer . next_is ( " \\ " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    escape  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // FIXME: Support utf?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                key  =  key_lexer . consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 21:08:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( has_ctrl ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                key  =  ctrl ( key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 21:08:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            keys . append ( Key  {  key ,  alt  ?  Key : : Alt  :  Key : : None  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            alt  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            has_ctrl  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 21:08:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 10:07:00 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        GenericLexer  value_lexer  {  config_file - > read_entry ( " keybinds " ,  binding_key )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        StringBuilder  value_builder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( ! value_lexer . is_eof ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            value_builder . append ( value_lexer . consume_escaped_character ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  value  =  value_builder . string_view ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 21:08:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( value . starts_with ( " internal: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            configuration . set ( KeyBinding  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                keys , 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 21:08:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                KeyBinding : : Kind : : InternalFunction , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 10:07:00 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                value . substring_view ( 9 ,  value . length ( )  -  9 )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 21:08:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            configuration . set ( KeyBinding  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                keys , 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 21:08:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                KeyBinding : : Kind : : Insertion , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                value  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 19:13:52 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  configuration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : set_default_keybinds ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ctrl ( ' N ' ) ,  EDITOR_INTERNAL_FUNCTION ( search_forwards ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ctrl ( ' P ' ) ,  EDITOR_INTERNAL_FUNCTION ( search_backwards ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ctrl ( ' A ' ) ,  EDITOR_INTERNAL_FUNCTION ( go_home ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ctrl ( ' B ' ) ,  EDITOR_INTERNAL_FUNCTION ( cursor_left_character ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ctrl ( ' D ' ) ,  EDITOR_INTERNAL_FUNCTION ( erase_character_forwards ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ctrl ( ' E ' ) ,  EDITOR_INTERNAL_FUNCTION ( go_end ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ctrl ( ' F ' ) ,  EDITOR_INTERNAL_FUNCTION ( cursor_right_character ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // ^H: ctrl('H') == '\b'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ctrl ( ' H ' ) ,  EDITOR_INTERNAL_FUNCTION ( erase_character_backwards ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-13 12:59:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // DEL - Some terminals send this instead of ^H.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ( char ) 127 ,  EDITOR_INTERNAL_FUNCTION ( erase_character_backwards ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    register_key_input_callback ( ctrl ( ' K ' ) ,  EDITOR_INTERNAL_FUNCTION ( erase_to_end ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ctrl ( ' L ' ) ,  EDITOR_INTERNAL_FUNCTION ( clear_screen ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ctrl ( ' R ' ) ,  EDITOR_INTERNAL_FUNCTION ( enter_search ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ctrl ( ' T ' ) ,  EDITOR_INTERNAL_FUNCTION ( transpose_characters ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( ' \n ' ,  EDITOR_INTERNAL_FUNCTION ( finish ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-17 21:41:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // ^X^E: Edit in external editor
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( Vector < Key >  {  ctrl ( ' X ' ) ,  ctrl ( ' E ' )  } ,  EDITOR_INTERNAL_FUNCTION ( edit_in_external_editor ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // ^[.: alt-.: insert last arg of previous command (similar to `!$`)
 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    register_key_input_callback ( Key  {  ' . ' ,  Key : : Alt  } ,  EDITOR_INTERNAL_FUNCTION ( insert_last_words ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( Key  {  ' b ' ,  Key : : Alt  } ,  EDITOR_INTERNAL_FUNCTION ( cursor_left_word ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( Key  {  ' f ' ,  Key : : Alt  } ,  EDITOR_INTERNAL_FUNCTION ( cursor_right_word ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // ^[^H: alt-backspace: backward delete word
 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    register_key_input_callback ( Key  {  ' \b ' ,  Key : : Alt  } ,  EDITOR_INTERNAL_FUNCTION ( erase_alnum_word_backwards ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( Key  {  ' d ' ,  Key : : Alt  } ,  EDITOR_INTERNAL_FUNCTION ( erase_alnum_word_forwards ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( Key  {  ' c ' ,  Key : : Alt  } ,  EDITOR_INTERNAL_FUNCTION ( capitalize_word ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( Key  {  ' l ' ,  Key : : Alt  } ,  EDITOR_INTERNAL_FUNCTION ( lowercase_word ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( Key  {  ' u ' ,  Key : : Alt  } ,  EDITOR_INTERNAL_FUNCTION ( uppercase_word ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( Key  {  ' t ' ,  Key : : Alt  } ,  EDITOR_INTERNAL_FUNCTION ( transpose_words ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-24 16:50:16 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Register these last to all the user to override the previous key bindings
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Normally ^W. `stty werase \^n` can change it to ^N (or something else).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( m_termios . c_cc [ VWERASE ] ,  EDITOR_INTERNAL_FUNCTION ( erase_word_backwards ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Normally ^U. `stty kill \^n` can change it to ^N (or something else).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( m_termios . c_cc [ VKILL ] ,  EDITOR_INTERNAL_FUNCTION ( kill_line ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    register_key_input_callback ( m_termios . c_cc [ VERASE ] ,  EDITOR_INTERNAL_FUNCTION ( erase_character_backwards ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-30 08:19:47 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Editor : : Editor ( Configuration  configuration )  
						 
					
						
							
								
									
										
										
										
											2020-05-19 08:42:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    :  m_configuration ( move ( configuration ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-01-09 03:40:07 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_always_refresh  =  m_configuration . refresh_behaviour  = =  Configuration : : RefreshBehaviour : : Eager ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_pending_chars  =  ByteBuffer : : create_uninitialized ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-06 19:58:11 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    get_terminal_size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-04 11:04:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_suggestion_display  =  make < XtermSuggestionDisplay > ( m_num_lines ,  m_num_columns ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-06 19:58:11 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Editor : : ~ Editor ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_initialized ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        restore ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-16 09:45:22 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : ensure_free_lines_from_origin ( size_t  count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( count  >  m_num_lines )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // It's hopeless...
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TODO ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_origin_row  +  count  < =  m_num_lines ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  diff  =  m_origin_row  +  count  -  m_num_lines  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    out ( stderr ,  " \x1b [{}S " ,  diff ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fflush ( stderr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_origin_row  - =  diff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_refresh_needed  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_chars_touched_in_the_middle  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-06 19:58:11 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : get_terminal_size ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    struct  winsize  ws ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-17 22:00:03 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-09 19:31:15 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ioctl ( STDERR_FILENO ,  TIOCGWINSZ ,  & ws )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        m_num_columns  =  80 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 13:29:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_num_lines  =  25 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        m_num_columns  =  ws . ws_col ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 13:29:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_num_lines  =  ws . ws_row ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 13:34:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : add_to_history ( const  String &  line )  
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-25 23:45:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( line . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 23:35:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    String  histcontrol  =  getenv ( " HISTCONTROL " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  ignoredups  =  histcontrol  = =  " ignoredups "  | |  histcontrol  = =  " ignoreboth " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  ignorespace  =  histcontrol  = =  " ignorespace "  | |  histcontrol  = =  " ignoreboth " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 18:58:42 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ignoredups  & &  ! m_history . is_empty ( )  & &  line  = =  m_history . last ( ) . entry ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 23:35:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ignorespace  & &  line . starts_with ( '   ' ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( ( m_history . size ( )  +  1 )  >  m_history_capacity ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_history . take_first ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 18:58:42 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    struct  timeval  tv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    gettimeofday ( & tv ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_history . append ( {  line ,  tv . tv_sec  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-11 15:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_history_dirty  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 23:25:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Editor : : load_history ( const  String &  path )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  history_file  =  Core : : File : : construct ( path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-12 13:56:43 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! history_file - > open ( Core : : OpenMode : : ReadOnly ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 23:25:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 18:58:42 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  data  =  history_file - > read_all ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  hist  =  StringView  {  data . data ( ) ,  data . size ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  str  :  hist . split_view ( " \n \n " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 18:12:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  it  =  str . find ( " :: " ) . value_or ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 18:58:42 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  time  =  str . substring_view ( 0 ,  it ) . to_uint < time_t > ( ) . value_or ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  string  =  str . substring_view ( it  = =  0  ?  it  :  it  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_history . append ( {  string ,  time  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 23:25:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 18:58:42 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								template < typename  It0 ,  typename  It1 ,  typename  OutputT ,  typename  MapperT ,  typename  LessThan >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  merge ( It0 & &  begin0 ,  const  It0 &  end0 ,  It1 & &  begin1 ,  const  It1 &  end1 ,  OutputT &  output ,  MapperT  left_mapper ,  LessThan  less_than )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( begin0  = =  end0  & &  begin1  = =  end1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( begin0  = =  end0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto & &  right  =  * begin1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( output . last ( ) . entry  ! =  right . entry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                output . append ( right ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + begin1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto & &  left  =  left_mapper ( * begin0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( left . entry . is_whitespace ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + begin0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( begin1  = =  end1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( output . last ( ) . entry  ! =  left . entry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                output . append ( left ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + begin0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto & &  right  =  * begin1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( less_than ( left ,  right ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( output . last ( ) . entry  ! =  left . entry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                output . append ( left ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + begin0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( output . last ( ) . entry  ! =  right . entry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                output . append ( right ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + begin1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( right . entry  = =  left . entry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                + + begin0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 23:25:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Editor : : save_history ( const  String &  path )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-01-11 18:58:42 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < HistoryEntry >  final_history  {  {  " " ,  0  }  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-12 13:56:43 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  file_or_error  =  Core : : File : : open ( path ,  Core : : OpenMode : : ReadWrite ,  0600 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 18:58:42 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( file_or_error . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  file  =  file_or_error . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        merge ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            file - > line_begin ( ) ,  file - > line_end ( ) ,  m_history . begin ( ) ,  m_history . end ( ) ,  final_history , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ ] ( StringView  str )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-12 23:31:23 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto  it  =  str . find ( " :: " ) . value_or ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 18:58:42 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto  time  =  str . substring_view ( 0 ,  it ) . to_uint < time_t > ( ) . value_or ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  string  =  str . substring_view ( it  = =  0  ?  it  :  it  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  HistoryEntry  {  string ,  time  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ ] ( const  HistoryEntry &  left ,  const  HistoryEntry &  right )  {  return  left . timestamp  <  right . timestamp ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-12 13:56:43 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  file_or_error  =  Core : : File : : open ( path ,  Core : : OpenMode : : WriteOnly ,  0600 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 23:25:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( file_or_error . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 18:58:42 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  file  =  file_or_error . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    final_history . take_first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( const  auto &  entry  :  final_history ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        file - > write ( String : : formatted ( " {}::{} \n \n " ,  entry . timestamp ,  entry . entry ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-11 15:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_history_dirty  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 23:25:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 13:34:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : clear_line ( )  
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  m_cursor ;  + + i ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-09 19:31:15 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        fputc ( 0x8 ,  stderr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fputs ( " \033 [K " ,  stderr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fflush ( stderr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 04:03:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_chars_touched_in_the_middle  =  buffer ( ) . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-05 15:31:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_buffer . clear ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    m_cursor  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_inline_search_cursor  =  m_cursor ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 18:06:43 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : insert ( const  Utf32View &  string )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  string . length ( ) ;  + + i ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        insert ( string . code_points ( ) [ i ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 18:06:43 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 13:34:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : insert ( const  String &  string )  
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  ch  :  Utf8View  {  string  } ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 13:29:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        insert ( ch ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-06 14:01:56 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : insert ( const  StringView &  string_view )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  ch  :  Utf8View  {  string_view  } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        insert ( ch ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : insert ( const  u32  cp )  
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    StringBuilder  builder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    builder . append ( Utf32View ( & cp ,  1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  str  =  builder . build ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_pending_chars . append ( str . characters ( ) ,  str . length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    readjust_anchored_styles ( m_cursor ,  ModificationKind : : Insertion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( m_cursor  = =  m_buffer . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_buffer . append ( cp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        m_cursor  =  m_buffer . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_inline_search_cursor  =  m_cursor ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_buffer . insert ( m_cursor ,  cp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    + + m_chars_touched_in_the_middle ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    + + m_cursor ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_inline_search_cursor  =  m_cursor ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : register_key_input_callback ( const  KeyBinding &  binding )  
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( binding . kind  = =  KeyBinding : : Kind : : InternalFunction )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  internal_function  =  find_internal_function ( binding . binding ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! internal_function )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 21:13:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            dbgln ( " LibLine: Unknown internal function '{}' " ,  binding . binding ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  register_key_input_callback ( binding . keys ,  move ( internal_function ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  register_key_input_callback ( binding . keys ,  [ binding  =  String ( binding . binding ) ] ( auto &  editor )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        editor . insert ( binding ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  size_t  code_point_length_in_utf8 ( u32  code_point )  
						 
					
						
							
								
									
										
										
										
											2020-05-18 21:35:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( code_point  < =  0x7f ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 21:35:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( code_point  < =  0x07ff ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 21:35:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( code_point  < =  0xffff ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 21:35:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  3 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( code_point  < =  0x10ffff ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 21:35:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// buffer [ 0 1 2 3 . . . A . . . B . . . M . . . N ]
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//                        ^       ^       ^       ^
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//                        |       |       |       +- end of buffer
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//                        |       |       +- scan offset = M
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//                        |       +- range end = M - B
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//                        +- range start = M - A
  
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// This method converts a byte range defined by [start_byte_offset, end_byte_offset] to a code_point range [M - A, M - B] as shown in the diagram above.
  
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// If `reverse' is true, A and B are before M, if not, A and B are after M.
  
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Editor : : CodepointRange  Editor : : byte_offset_range_to_code_point_offset_range ( size_t  start_byte_offset ,  size_t  end_byte_offset ,  size_t  scan_code_point_offset ,  bool  reverse )  const  
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  byte_offset  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    size_t  code_point_offset  =  scan_code_point_offset  +  ( reverse  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    CodepointRange  range ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! reverse )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( code_point_offset  > =  m_buffer . size ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( code_point_offset  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( byte_offset  >  end_byte_offset ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( byte_offset  <  start_byte_offset ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + range . start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( byte_offset  <  end_byte_offset ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + range . end ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        byte_offset  + =  code_point_length_in_utf8 ( m_buffer [ reverse  ?  - - code_point_offset  :  code_point_offset + + ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  range ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : stylize ( const  Span &  span ,  const  Style &  style )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( style . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 21:35:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  start  =  span . beginning ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  end  =  span . end ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( span . mode ( )  = =  Span : : ByteOriented )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  offsets  =  byte_offset_range_to_code_point_offset_range ( start ,  end ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 21:35:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        start  =  offsets . start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        end  =  offsets . end ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 21:35:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  spans_starting  =  style . is_anchored ( )  ?  m_current_spans . m_anchored_spans_starting  :  m_current_spans . m_spans_starting ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  spans_ending  =  style . is_anchored ( )  ?  m_current_spans . m_anchored_spans_ending  :  m_current_spans . m_spans_ending ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  starting_map  =  spans_starting . get ( start ) . value_or ( { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 21:35:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! starting_map . contains ( end ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_refresh_needed  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 21:35:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    starting_map . set ( end ,  style ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    spans_starting . set ( start ,  starting_map ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  ending_map  =  spans_ending . get ( end ) . value_or ( { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 21:35:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! ending_map . contains ( start ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_refresh_needed  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 21:35:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ending_map . set ( start ,  style ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    spans_ending . set ( end ,  ending_map ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : suggest ( size_t  invariant_offset ,  size_t  static_offset ,  Span : : Mode  offset_mode )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  internal_static_offset  =  static_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  internal_invariant_offset  =  invariant_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( offset_mode  = =  Span : : Mode : : ByteOriented )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: We're assuming that invariant_offset points to the end of the available data
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //        this is not necessarily true, but is true in most cases.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  offsets  =  byte_offset_range_to_code_point_offset_range ( internal_static_offset ,  internal_invariant_offset  +  internal_static_offset ,  m_cursor  -  1 ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        internal_static_offset  =  offsets . start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        internal_invariant_offset  =  offsets . end  -  offsets . start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-22 03:52:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_suggestion_manager . set_suggestion_variants ( internal_static_offset ,  internal_invariant_offset ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 19:52:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : initialize ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_initialized ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  termios  termios ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tcgetattr ( 0 ,  & termios ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_default_termios  =  termios ;  // grab a copy to restore
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-17 22:00:03 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    get_terminal_size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 19:52:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 09:58:47 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_configuration . operation_mode  = =  Configuration : : Unset )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-09 19:31:15 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  istty  =  isatty ( STDIN_FILENO )  & &  isatty ( STDERR_FILENO ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 09:58:47 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! istty )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_configuration . set ( Configuration : : NonInteractive ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto *  term  =  getenv ( " TERM " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( StringView  {  term  } . starts_with ( " xterm " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_configuration . set ( Configuration : : Full ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_configuration . set ( Configuration : : NoEscapeSequences ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 19:52:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Because we use our own line discipline which includes echoing,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // we disable ICANON and ECHO.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_configuration . operation_mode  = =  Configuration : : Full )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        termios . c_lflag  & =  ~ ( ECHO  |  ICANON ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tcsetattr ( 0 ,  TCSANOW ,  & termios ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_termios  =  termios ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 15:24:26 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    set_default_keybinds ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  keybind  :  m_configuration . keybindings ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        register_key_input_callback ( keybind ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-09 03:40:07 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_configuration . m_signal_mode  = =  Configuration : : WithSignalHandlers )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_signal_handlers . append ( Core : : EventLoop : : register_signal ( SIGINT ,  [ this ] ( int )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            interrupted ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:09:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-09 03:40:07 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_signal_handlers . append ( Core : : EventLoop : : register_signal ( SIGWINCH ,  [ this ] ( int )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            resized ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:09:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 19:52:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_initialized  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-24 16:50:16 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : refetch_default_termios ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  termios  termios ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tcgetattr ( 0 ,  & termios ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_default_termios  =  termios ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_configuration . operation_mode  = =  Configuration : : Full ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        termios . c_lflag  & =  ~ ( ECHO  |  ICANON ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_termios  =  termios ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : interrupted ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-01-09 03:40:07 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_is_searching ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  m_search_editor - > interrupted ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_is_editing ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_was_interrupted  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    handle_interrupt_event ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-07 03:12:17 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_finish  | |  ! m_previous_interrupt_was_handled_as_interrupt ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_finish  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        OutputFileStream  stderr_stream  {  stderr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        reposition_cursor ( stderr_stream ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_suggestion_display - > cleanup ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            reposition_cursor ( stderr_stream ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        stderr_stream . write ( " \n " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_buffer . clear ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 04:03:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_chars_touched_in_the_middle  =  buffer ( ) . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_is_editing  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    restore ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-09 03:40:07 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_notifier - > set_enabled ( false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:22:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_notifier  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Core : : EventLoop : : current ( ) . quit ( Retry ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 12:43:36 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : resized ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_was_resized  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_previous_num_columns  =  m_num_columns ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    get_terminal_size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 06:10:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_has_origin_reset_scheduled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Reset the origin, but make sure it doesn't blow up if we can't read it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( set_origin ( false ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            handle_resize_event ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            deferred_invoke ( [ this ] ( auto & )  {  handle_resize_event ( true ) ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_has_origin_reset_scheduled  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Editor : : handle_resize_event ( bool  reset_origin )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_has_origin_reset_scheduled  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( reset_origin  & &  ! set_origin ( false ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_has_origin_reset_scheduled  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  deferred_invoke ( [ this ] ( auto & )  {  handle_resize_event ( true ) ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    set_origin ( m_origin_row ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    OutputFileStream  stderr_stream  {  stderr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    reposition_cursor ( stderr_stream ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 12:43:36 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_suggestion_display - > redisplay ( m_suggestion_manager ,  m_num_lines ,  m_num_columns ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    reposition_cursor ( stderr_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 12:43:36 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_is_searching ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_search_editor - > resized ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : really_quit_event_loop ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_finish  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        OutputFileStream  stderr_stream  {  stderr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        reposition_cursor ( stderr_stream ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        stderr_stream . write ( " \n " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  string  =  line ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_buffer . clear ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 04:03:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_chars_touched_in_the_middle  =  buffer ( ) . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_is_editing  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 14:29:53 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_initialized ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        restore ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_returned_line  =  string ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-09 03:40:07 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_notifier - > set_enabled ( false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:22:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_notifier  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Core : : EventLoop : : current ( ) . quit ( Exit ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								auto  Editor : : get_line ( const  String &  prompt )  - >  Result < String ,  Editor : : Error >  
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    initialize ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_is_editing  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_configuration . operation_mode  = =  Configuration : : NoEscapeSequences  | |  m_configuration . operation_mode  = =  Configuration : : NonInteractive )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Do not use escape sequences, instead, use LibC's getline.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        size_t  size  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        char *  line  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Show the prompt only on interactive mode (NoEscapeSequences in this case).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_configuration . operation_mode  ! =  Configuration : : NonInteractive ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fputs ( prompt . characters ( ) ,  stderr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  line_length  =  getline ( & line ,  & size ,  stdin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // getline() returns -1 and sets errno=0 on EOF.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( line_length  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( line ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 09:58:47 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                free ( line ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( errno  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  Error : : Eof ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 09:58:47 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Error : : ReadFailure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        restore ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( line )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            String  result  {  line ,  ( size_t ) line_length ,  Chomp  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            free ( line ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 19:52:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Error : : ReadFailure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  old_cols  =  m_num_columns ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  old_lines  =  m_num_lines ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    get_terminal_size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-17 22:00:03 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_configuration . enable_bracketed_paste ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        fprintf ( stderr ,  " \x1b [?2004h " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-24 16:30:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_num_columns  ! =  old_cols  | |  m_num_lines  ! =  old_lines ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_refresh_needed  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    set_prompt ( prompt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    reset ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    strip_styles ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        OutputFileStream  stderr_stream  {  stderr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  prompt_lines  =  max ( current_prompt_metrics ( ) . line_metrics . size ( ) ,  1ul )  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  prompt_lines ;  + + i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            stderr_stream . write ( " \n " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VT : : move_relative ( - static_cast < int > ( prompt_lines ) ,  0 ,  stderr_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    set_origin ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_history_cursor  =  m_history . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    refresh_display ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Core : : EventLoop  loop ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_notifier  =  Core : : Notifier : : construct ( STDIN_FILENO ,  Core : : Notifier : : Read ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_notifier - > on_ready_to_read  =  [ & ]  {  try_update_once ( ) ;  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_incomplete_data . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        deferred_invoke ( [ & ] ( auto & )  {  try_update_once ( ) ;  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:53:24 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 02:02:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( loop . exec ( )  = =  Retry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  get_line ( prompt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:53:24 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  m_input_error . has_value ( )  ?  Result < String ,  Editor : : Error >  {  m_input_error . value ( )  }  :  Result < String ,  Editor : : Error >  {  m_returned_line  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:21:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Editor : : save_to ( JsonObject &  object )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Core : : Object : : save_to ( object ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    object . set ( " is_searching " ,  m_is_searching ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    object . set ( " is_editing " ,  m_is_editing ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    object . set ( " cursor_offset " ,  m_cursor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    object . set ( " needs_refresh " ,  m_refresh_needed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    object . set ( " unprocessed_characters " ,  m_incomplete_data . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    object . set ( " history_size " ,  m_history . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    object . set ( " current_prompt " ,  m_new_prompt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    object . set ( " was_interrupted " ,  m_was_interrupted ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    JsonObject  display_area ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:48:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    display_area . set ( " top_left_row " ,  m_origin_row ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    display_area . set ( " top_left_column " ,  m_origin_column ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:21:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    display_area . set ( " line_count " ,  num_lines ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    object . set ( " used_display_area " ,  move ( display_area ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:34:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 15:29:07 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : try_update_once ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_was_interrupted )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handle_interrupt_event ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    handle_read_event ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_always_refresh ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_refresh_needed  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    refresh_display ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_finish ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        really_quit_event_loop ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 16:26:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : handle_interrupt_event ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_was_interrupted  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-07 03:12:17 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_previous_interrupt_was_handled_as_interrupt  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 16:26:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_callback_machine . interrupted ( * this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_callback_machine . should_process_last_pressed_key ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 16:26:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-07 03:12:17 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_previous_interrupt_was_handled_as_interrupt  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-21 19:37:14 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    fprintf ( stderr ,  " ^C " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fflush ( stderr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 16:26:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( on_interrupt_handled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        on_interrupt_handled ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_buffer . clear ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 04:03:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_chars_touched_in_the_middle  =  buffer ( ) . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-20 20:04:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_cursor  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    finish ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 16:26:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : handle_read_event ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    char  keybuf [ 16 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ssize_t  nread  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_incomplete_data . size ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        nread  =  read ( 0 ,  keybuf ,  sizeof ( keybuf ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-13 14:22:47 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( nread  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( errno  = =  EINTR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! m_was_interrupted )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( m_was_resized ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-13 14:22:47 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                finish ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-25 16:57:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 16:26:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            handle_interrupt_event ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ScopedValueRollback  errno_restorer ( errno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        perror ( " read failed " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_input_error  =  Error : : ReadFailure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        finish ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_incomplete_data . append ( keybuf ,  nread ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nread  =  m_incomplete_data . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( nread  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_input_error  =  Error : : Empty ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        finish ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  reverse_tab  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Discard starting bytes until they make sense as utf-8.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  valid_bytes  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( nread )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Utf8View  {  StringView  {  m_incomplete_data . data ( ) ,  ( size_t ) nread  }  } . validate ( valid_bytes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( valid_bytes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_incomplete_data . take_first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        - - nread ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 14:47:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Utf8View  input_view  {  StringView  {  m_incomplete_data . data ( ) ,  valid_bytes  }  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    size_t  consumed_code_points  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 14:47:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-06 23:24:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  Vector < u8 ,  4 >  csi_parameter_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  Vector < u8 >  csi_intermediate_bytes ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 20:33:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < unsigned ,  4 >  csi_parameters ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    u8  csi_final ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 21:08:19 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    enum  CSIMod  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Shift  =  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Alt  =  2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Ctrl  =  4 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 20:33:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  code_point  :  input_view )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_finish ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        + + consumed_code_points ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( code_point  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        switch  ( m_state )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-06 10:52:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  InputState : : GotEscape : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            switch  ( code_point )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  ' [ ' : 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 20:33:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                m_state  =  InputState : : CSIExpectParameter ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            default :  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                m_callback_machine . key_pressed ( * this ,  {  code_point ,  Key : : Alt  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                m_state  =  InputState : : Free ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-31 22:04:32 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                cleanup_suggestions ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-06 13:26:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 20:33:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  InputState : : CSIExpectParameter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( code_point  > =  0x30  & &  code_point  < =  0x3f )  {  // '0123456789:;<=>?'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                csi_parameter_bytes . append ( code_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_state  =  InputState : : CSIExpectIntermediate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [[fallthrough]] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  InputState : : CSIExpectIntermediate : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( code_point  > =  0x20  & &  code_point  < =  0x2f )  {  // ' !"#$%&\'()*+,-./'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                csi_intermediate_bytes . append ( code_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_state  =  InputState : : CSIExpectFinal ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [[fallthrough]] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 21:08:19 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  InputState : : CSIExpectFinal :  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-24 16:30:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_state  =  m_previous_free_state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  is_in_paste  =  m_state  = =  InputState : : Paste ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 20:33:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            for  ( auto &  parameter  :  String : : copy ( csi_parameter_bytes ) . split ( ' ; ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( auto  value  =  parameter . to_uint ( ) ;  value . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    csi_parameters . append ( value . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    csi_parameters . append ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 21:08:19 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            unsigned  param1  =  0 ,  param2  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( csi_parameters . size ( )  > =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                param1  =  csi_parameters [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( csi_parameters . size ( )  > =  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                param2  =  csi_parameters [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            unsigned  modifiers  =  param2  ?  param2  -  1  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 20:33:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-24 16:30:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is_in_paste  & &  code_point  ! =  ' ~ '  & &  param1  ! =  201 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // The only valid escape to process in paste mode is the stop-paste sequence.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // so treat everything else as part of the pasted data.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                insert ( ' \x1b ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                insert ( ' [ ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                insert ( StringView  {  csi_parameter_bytes . data ( ) ,  csi_parameter_bytes . size ( )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                insert ( StringView  {  csi_intermediate_bytes . data ( ) ,  csi_intermediate_bytes . size ( )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                insert ( code_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! ( code_point  > =  0x40  & &  code_point  < =  0x7f ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dbgln ( " LibLine: Invalid CSI: {:02x} ({:c}) " ,  code_point ,  code_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            csi_final  =  code_point ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            csi_parameters . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            csi_parameter_bytes . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            csi_intermediate_bytes . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 20:33:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( csi_final  = =  ' Z ' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-06 02:27:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // 'reverse tab'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                reverse_tab  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-31 22:04:32 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            cleanup_suggestions ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 21:08:19 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 20:33:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            switch  ( csi_final )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-06 10:52:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  ' A ' :  // ^[[A: arrow up
 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                search_backwards ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-06 10:52:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  ' B ' :  // ^[[B: arrow down
 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                search_forwards ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-06 10:52:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  ' D ' :  // ^[[D: arrow left
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 21:15:07 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( modifiers  = =  CSIMod : : Alt  | |  modifiers  = =  CSIMod : : Ctrl ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    cursor_left_word ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    cursor_left_character ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-06 10:52:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  ' C ' :  // ^[[C: arrow right
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 21:15:07 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( modifiers  = =  CSIMod : : Alt  | |  modifiers  = =  CSIMod : : Ctrl ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    cursor_right_word ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    cursor_right_character ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-06 10:52:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  ' H ' :  // ^[[H: home
 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                go_home ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-06 10:52:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  ' F ' :  // ^[[F: end
 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                go_end ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 20:33:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  ' ~ ' : 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 21:08:19 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( param1  = =  3 )  {  // ^[[3~: delete
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 21:32:22 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( modifiers  = =  CSIMod : : Ctrl ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        erase_alnum_word_forwards ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        erase_character_forwards ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 20:33:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    m_search_offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-24 16:30:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( m_configuration . enable_bracketed_paste )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // ^[[200~: start bracketed paste
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // ^[[201~: end bracketed paste
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ! is_in_paste  & &  param1  = =  200 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        m_state  =  InputState : : Paste ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( is_in_paste  & &  param1  = =  201 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        m_state  =  InputState : : Free ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 20:33:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // ^[[5~: page up
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // ^[[6~: page down
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 10:02:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                dbgln ( " LibLine: Unhandled '~': {} " ,  param1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            default : 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 10:02:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                dbgln ( " LibLine: Unhandled final: {:02x} ({:c}) " ,  code_point ,  code_point ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-13 21:08:19 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  InputState : : Verbatim : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_state  =  InputState : : Free ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Verbatim mode will bypass all mechanisms and just insert the code point.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            insert ( code_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-24 16:30:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  InputState : : Paste : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( code_point  = =  27 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_previous_free_state  =  InputState : : Paste ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_state  =  InputState : : GotEscape ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            insert ( code_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  InputState : : Free : 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-24 16:30:44 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_previous_free_state  =  InputState : : Free ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( code_point  = =  27 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                m_callback_machine . key_pressed ( * this ,  code_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Note that this should also deal with explicitly registered keys
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // that would otherwise be interpreted as escapes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( m_callback_machine . should_process_last_pressed_key ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    m_state  =  InputState : : GotEscape ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( code_point  = =  22 )  {  // ^v
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_callback_machine . key_pressed ( * this ,  code_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( m_callback_machine . should_process_last_pressed_key ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    m_state  =  InputState : : Verbatim ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-31 22:04:32 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // There are no sequences past this point, so short of 'tab', we will want to cleanup the suggestions.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ArmedScopeGuard  suggestion_cleanup  {  [ this ]  {  cleanup_suggestions ( ) ;  }  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Normally ^D. `stty eof \^n` can change it to ^N (or something else), but Serenity doesn't have `stty` yet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Process this here since the keybinds might override its behaviour.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-07 07:37:54 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // This only applies when the buffer is empty. at any other time, the behaviour should be configurable.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( code_point  = =  m_termios . c_cc [ VEOF ]  & &  m_buffer . size ( )  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 20:38:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            finish_edit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 09:39:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_callback_machine . key_pressed ( * this ,  code_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! m_callback_machine . should_process_last_pressed_key ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_search_offset  =  0 ;  // reset search offset on any key
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( code_point  = =  ' \t '  | |  reverse_tab )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-31 22:04:32 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            suggestion_cleanup . disarm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! on_tab_complete ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Reverse tab can count as regular tab here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_times_tab_pressed + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 19:02:15 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            int  token_start  =  m_cursor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Ask for completions only on the first tab
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // and scan for the largest common prefix to display,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // further tabs simply show the cached completions.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( m_times_tab_pressed  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_suggestion_manager . set_suggestions ( on_tab_complete ( * this ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_prompt_lines_at_suggestion_initiation  =  num_lines ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( m_suggestion_manager . count ( )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // There are no suggestions, beep.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-09 19:31:15 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    fputc ( ' \a ' ,  stderr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    fflush ( stderr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 19:35:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 19:35:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Adjust already incremented / decremented index when switching tab direction.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( reverse_tab  & &  m_tab_direction  ! =  TabDirection : : Backward )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_suggestion_manager . previous ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_suggestion_manager . previous ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_tab_direction  =  TabDirection : : Backward ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! reverse_tab  & &  m_tab_direction  ! =  TabDirection : : Forward )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_suggestion_manager . next ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_suggestion_manager . next ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_tab_direction  =  TabDirection : : Forward ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            reverse_tab  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 18:06:43 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            SuggestionManager : : CompletionMode  completion_mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            switch  ( m_times_tab_pressed )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                completion_mode  =  SuggestionManager : : CompletePrefix ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                completion_mode  =  SuggestionManager : : ShowSuggestions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                completion_mode  =  SuggestionManager : : CycleSuggestions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 18:06:43 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  completion_result  =  m_suggestion_manager . attempt_completion ( completion_mode ,  token_start ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  new_cursor  =  m_cursor  +  completion_result . new_cursor_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( size_t  i  =  completion_result . offset_region_to_remove . start ;  i  <  completion_result . offset_region_to_remove . end ;  + + i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                remove_at_index ( new_cursor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_cursor  =  new_cursor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_inline_search_cursor  =  new_cursor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_refresh_needed  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 04:03:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_chars_touched_in_the_middle + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            for  ( auto &  view  :  completion_result . insert ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                insert ( view ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 19:02:15 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            OutputFileStream  stderr_stream  {  stderr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            reposition_cursor ( stderr_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 04:03:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( completion_result . style_to_apply . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Apply the style of the last suggestion.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                readjust_anchored_styles ( m_suggestion_manager . current_suggestion ( ) . start_index ,  ModificationKind : : ForcedOverlapRemoval ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                stylize ( {  m_suggestion_manager . current_suggestion ( ) . start_index ,  m_cursor ,  Span : : Mode : : CodepointOriented  } ,  completion_result . style_to_apply . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 19:02:15 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            switch  ( completion_result . new_completion_mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  SuggestionManager : : DontComplete : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_times_tab_pressed  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  SuggestionManager : : CompletePrefix : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                + + m_times_tab_pressed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 19:02:15 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( m_times_tab_pressed  >  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( m_suggestion_manager . count ( )  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( m_suggestion_display - > cleanup ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        reposition_cursor ( stderr_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 11:55:42 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    m_suggestion_display - > set_initial_prompt_lines ( m_prompt_lines_at_suggestion_initiation ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    m_suggestion_display - > display ( m_suggestion_manager ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 11:55:42 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:48:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    m_origin_row  =  m_suggestion_display - > origin_row ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-22 03:52:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( m_times_tab_pressed  >  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( m_tab_direction  = =  TabDirection : : Forward ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    m_suggestion_manager . next ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    m_suggestion_manager . previous ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( m_suggestion_manager . count ( )  <  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // We have none, or just one suggestion,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // we should just commit that and continue
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // after it, as if it were auto-completed.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                suggest ( 0 ,  0 ,  Span : : CodepointOriented ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                m_times_tab_pressed  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_suggestion_manager . reset ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-22 14:02:17 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                m_suggestion_display - > finish ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 13:29:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-11 12:22:55 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // If we got here, manually cleanup the suggestions and then insert the new code point.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        suggestion_cleanup . disarm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        cleanup_suggestions ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        insert ( code_point ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( consumed_code_points  = =  m_incomplete_data . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_incomplete_data . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  consumed_code_points ;  + + i ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_incomplete_data . take_first ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 15:29:07 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_incomplete_data . is_empty ( )  & &  ! m_finish ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        deferred_invoke ( [ & ] ( auto & )  {  try_update_once ( ) ;  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-31 22:04:32 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : cleanup_suggestions ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_times_tab_pressed )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Apply the style of the last suggestion.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        readjust_anchored_styles ( m_suggestion_manager . current_suggestion ( ) . start_index ,  ModificationKind : : ForcedOverlapRemoval ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        stylize ( {  m_suggestion_manager . current_suggestion ( ) . start_index ,  m_cursor ,  Span : : Mode : : CodepointOriented  } ,  m_suggestion_manager . current_suggestion ( ) . style ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // We probably have some suggestions drawn,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // let's clean them up.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_suggestion_display - > cleanup ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            OutputFileStream  stderr_stream  {  stderr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            reposition_cursor ( stderr_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-31 22:04:32 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_refresh_needed  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_suggestion_manager . reset ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        suggest ( 0 ,  0 ,  Span : : CodepointOriented ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_suggestion_display - > finish ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_times_tab_pressed  =  0 ;  // Safe to say if we get here, the user didn't press TAB
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-07 00:44:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Editor : : search ( const  StringView &  phrase ,  bool  allow_empty ,  bool  from_beginning )  
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  last_matching_offset  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-23 17:44:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  found  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Do not search for empty strings.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( allow_empty  | |  phrase . length ( )  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        size_t  search_offset  =  m_search_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( size_t  i  =  m_history_cursor ;  i  >  0 ;  - - i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-07 00:44:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  entry  =  m_history [ i  -  1 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 18:58:42 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  contains  =  from_beginning  ?  entry . entry . starts_with ( phrase )  :  entry . entry . contains ( phrase ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( contains )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                last_matching_offset  =  i  -  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-23 17:44:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( search_offset  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    found  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-23 17:44:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                - - search_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-23 17:44:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! found )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-09 19:31:15 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            fputc ( ' \a ' ,  stderr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fflush ( stderr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-23 17:44:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( found )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-24 10:17:42 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // We plan to clear the buffer, so mark the entire thing touched.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_chars_touched_in_the_middle  =  m_buffer . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-23 17:44:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_buffer . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_cursor  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 18:58:42 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        insert ( m_history [ last_matching_offset ] . entry ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-23 17:44:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Always needed, as we have cleared the buffer above.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_refresh_needed  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-23 17:44:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  found ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-20 17:20:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 14:06:46 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : recalculate_origin ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Changing the columns can affect our origin if
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 14:06:46 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // the new size is smaller than our prompt, which would
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // cause said prompt to take up more space, so we should
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // compensate for that.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_cached_prompt_metrics . max_line_length  > =  m_num_columns )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  added_lines  =  ( m_cached_prompt_metrics . max_line_length  +  1 )  /  m_num_columns  -  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:48:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_origin_row  + =  added_lines ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 14:06:46 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // We also need to recalculate our cursor position,
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 14:06:46 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // but that will be calculated and applied at the next
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // refresh cycle.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 14:06:46 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:34:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : cleanup ( )  
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-06-29 20:08:02 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  current_buffer_metrics  =  actual_rendered_string_metrics ( buffer_view ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  new_lines  =  current_prompt_metrics ( ) . lines_with_addition ( current_buffer_metrics ,  m_num_columns ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  shown_lines  =  num_lines ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( new_lines  <  shown_lines ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_extra_forward_lines  =  max ( shown_lines  -  new_lines ,  m_extra_forward_lines ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    OutputFileStream  stderr_stream  {  stderr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    reposition_cursor ( stderr_stream ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  current_line  =  num_lines ( )  -  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VT : : clear_lines ( current_line ,  m_extra_forward_lines ,  stderr_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_extra_forward_lines  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    reposition_cursor ( stderr_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:34:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
									
										
										
										
											2020-04-10 09:53:22 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-19 23:34:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : refresh_display ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    DuplexMemoryStream  output_stream ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopeGuard  flush_stream  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  buffer  =  output_stream . copy_into_contiguous_buffer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( buffer . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fwrite ( buffer . data ( ) ,  sizeof ( char ) ,  buffer . size ( ) ,  stderr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 09:53:22 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  has_cleaned_up  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Someone changed the window size, figure it out
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // and react to it, we might need to redraw.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 09:53:22 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_was_resized )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-06 19:58:11 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_previous_num_columns  ! =  m_num_columns )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // We need to cleanup and redo everything.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 09:53:22 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_cached_prompt_valid  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_refresh_needed  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-06 19:58:11 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            swap ( m_previous_num_columns ,  m_num_columns ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 14:06:46 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            recalculate_origin ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 09:53:22 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            cleanup ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-06 19:58:11 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            swap ( m_previous_num_columns ,  m_num_columns ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 09:53:22 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            has_cleaned_up  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:31:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_was_resized  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 09:53:22 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:31:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // We might be at the last line, and have more than one line;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Refreshing the display will cause the terminal to scroll,
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // so note that fact and bring origin up, making sure to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // reserve the space for however many lines we move it up.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:31:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  current_num_lines  =  num_lines ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_origin_row  +  current_num_lines  >  m_num_lines )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( current_num_lines  >  m_num_lines )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( size_t  i  =  0 ;  i  <  m_num_lines ;  + + i ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                output_stream . write ( " \n " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:31:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_origin_row  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  old_origin_row  =  m_origin_row ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:31:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_origin_row  =  m_num_lines  -  current_num_lines  +  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            for  ( size_t  i  =  0 ;  i  <  old_origin_row  -  m_origin_row ;  + + i ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                output_stream . write ( " \n " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:31:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 15:16:53 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Do not call hook on pure cursor movement.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_cached_prompt_valid  & &  ! m_refresh_needed  & &  m_pending_chars . size ( )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Probably just moving around.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        reposition_cursor ( output_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 15:16:53 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_cached_buffer_metrics  =  actual_rendered_string_metrics ( buffer_view ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_drawn_end_of_line_offset  =  m_buffer . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 15:16:53 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( on_display_refresh ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        on_display_refresh ( * this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_cached_prompt_valid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! m_refresh_needed  & &  m_cursor  = =  m_buffer . size ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Just write the characters out and continue,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // no need to refresh the entire line.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            output_stream . write ( m_pending_chars ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_pending_chars . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_drawn_cursor  =  m_cursor ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_drawn_end_of_line_offset  =  m_buffer . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_cached_buffer_metrics  =  actual_rendered_string_metrics ( buffer_view ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_drawn_spans  =  m_current_spans ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  apply_styles  =  [ & ,  empty_styles  =  HashMap < u32 ,  Style >  { } ] ( size_t  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  ends  =  m_current_spans . m_spans_ending . get ( i ) . value_or ( empty_styles ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  starts  =  m_current_spans . m_spans_starting . get ( i ) . value_or ( empty_styles ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  anchored_ends  =  m_current_spans . m_anchored_spans_ending . get ( i ) . value_or ( empty_styles ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  anchored_starts  =  m_current_spans . m_anchored_spans_starting . get ( i ) . value_or ( empty_styles ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ends . size ( )  | |  anchored_ends . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Style  style ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  applicable_style  :  ends ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                style . unify_with ( applicable_style . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  applicable_style  :  anchored_ends ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                style . unify_with ( applicable_style . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Disable any style that should be turned off.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VT : : apply_style ( style ,  output_stream ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Reapply styles for overlapping spans that include this one.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            style  =  find_applicable_style ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VT : : apply_style ( style ,  output_stream ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( starts . size ( )  | |  anchored_starts . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Style  style ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  applicable_style  :  starts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                style . unify_with ( applicable_style . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  applicable_style  :  anchored_starts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                style . unify_with ( applicable_style . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Set new styles.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VT : : apply_style ( style ,  output_stream ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  print_character_at  =  [ & ] ( size_t  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        StringBuilder  builder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  c  =  m_buffer [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bool  should_print_masked  =  is_ascii_control ( c )  & &  c  ! =  ' \n ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-13 12:58:06 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bool  should_print_caret  =  c  <  64  & &  should_print_masked ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( should_print_caret ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            builder . appendff ( " ^{:c} " ,  c  +  64 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-13 12:58:06 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else  if  ( should_print_masked ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            builder . appendff ( " \\ x{:0>2x} " ,  c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            builder . append ( Utf32View  {  & c ,  1  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-13 12:58:06 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( should_print_masked ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            output_stream . write ( " \033 [7m " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        output_stream . write ( builder . string_view ( ) . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-13 12:58:06 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( should_print_masked ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            output_stream . write ( " \033 [27m " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // If there have been no changes to previous sections of the line (style or text)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // just append the new text with the appropriate styles.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 04:03:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_always_refresh  & &  m_cached_prompt_valid  & &  m_chars_touched_in_the_middle  = =  0  & &  m_drawn_spans . contains_up_to_offset ( m_current_spans ,  m_drawn_cursor ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  initial_style  =  find_applicable_style ( m_drawn_end_of_line_offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VT : : apply_style ( initial_style ,  output_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( size_t  i  =  m_drawn_end_of_line_offset ;  i  <  m_buffer . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            apply_styles ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print_character_at ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VT : : apply_style ( Style : : reset_style ( ) ,  output_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_pending_chars . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_refresh_needed  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_cached_buffer_metrics  =  actual_rendered_string_metrics ( buffer_view ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_chars_touched_in_the_middle  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-24 09:38:46 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_drawn_cursor  =  m_cursor ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_drawn_end_of_line_offset  =  m_buffer . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // No need to reposition the cursor, the cursor is already where it needs to be.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  constexpr  ( LINE_EDITOR_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_cached_prompt_valid  & &  m_chars_touched_in_the_middle  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  x  =  m_drawn_spans . contains_up_to_offset ( m_current_spans ,  m_drawn_cursor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln ( " Contains: {} At offset: {} " ,  x ,  m_drawn_cursor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln ( " Drawn Spans: " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  sentry  :  m_drawn_spans . m_spans_starting )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for  ( auto &  entry  :  sentry . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    dbgln ( " {}-{}: {} " ,  sentry . key ,  entry . key ,  entry . value . to_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln ( " ========================================================================== " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln ( " Current Spans: " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  sentry  :  m_current_spans . m_spans_starting )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for  ( auto &  entry  :  sentry . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    dbgln ( " {}-{}: {} " ,  sentry . key ,  entry . key ,  entry . value . to_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Ouch, reflow entire line.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! has_cleaned_up )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        cleanup ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VT : : move_absolute ( m_origin_row ,  m_origin_column ,  output_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    output_stream . write ( m_new_prompt . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VT : : clear_to_end_of_line ( output_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    StringBuilder  builder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  m_buffer . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        apply_styles ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_character_at ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VT : : apply_style ( Style : : reset_style ( ) ,  output_stream ) ;  // don't bleed to EOL
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_pending_chars . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_refresh_needed  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_cached_buffer_metrics  =  actual_rendered_string_metrics ( buffer_view ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_chars_touched_in_the_middle  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_drawn_spans  =  m_current_spans ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_drawn_end_of_line_offset  =  m_buffer . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_cached_prompt_valid  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    reposition_cursor ( output_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : strip_styles ( bool  strip_anchored )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_current_spans . m_spans_starting . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_current_spans . m_spans_ending . clear ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( strip_anchored )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_current_spans . m_anchored_spans_starting . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_current_spans . m_anchored_spans_ending . clear ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_refresh_needed  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : reposition_cursor ( OutputStream &  stream ,  bool  to_end )  
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-06-29 20:08:02 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  cursor  =  m_cursor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  saved_cursor  =  m_cursor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( to_end ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        cursor  =  m_buffer . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_cursor  =  cursor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_drawn_cursor  =  cursor ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  line  =  cursor_line ( )  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  column  =  offset_in_line ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-16 09:45:22 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ensure_free_lines_from_origin ( line ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( column  +  m_origin_column  < =  m_num_columns ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VT : : move_absolute ( line  +  m_origin_row ,  column  +  m_origin_column ,  stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-29 20:08:02 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_cursor  =  saved_cursor ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  VT : : move_absolute ( u32  row ,  u32  col ,  OutputStream &  stream )  
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    stream . write ( String : : formatted ( " \033 [{};{}H " ,  row ,  col ) . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  VT : : move_relative ( int  row ,  int  col ,  OutputStream &  stream )  
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    char  x_op  =  ' A ' ,  y_op  =  ' D ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:48:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( row  >  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        x_op  =  ' B ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:48:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        row  =  - row ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( col  >  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        y_op  =  ' C ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:48:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        col  =  - col ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:48:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( row  >  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        stream . write ( String : : formatted ( " \033 [{}{} " ,  row ,  x_op ) . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 00:48:40 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( col  >  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        stream . write ( String : : formatted ( " \033 [{}{} " ,  col ,  y_op ) . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Style  Editor : : find_applicable_style ( size_t  offset )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Walk through our styles and merge all that fit in the offset.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 19:15:23 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  style  =  Style : : reset_style ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  unify  =  [ & ] ( auto &  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( entry . key  > =  offset ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  style_value  :  entry . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( style_value . key  < =  offset ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 19:15:23 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            style . unify_with ( style_value . value ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  entry  :  m_current_spans . m_spans_starting )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        unify ( entry ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  entry  :  m_current_spans . m_anchored_spans_starting )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        unify ( entry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  style ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-10 12:27:36 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  Style : : Background : : to_vt_escape ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is_default ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-10 12:27:36 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_is_rgb )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-21 22:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  String : : formatted ( " \ e[48;2;{};{};{}m " ,  m_rgb_color [ 0 ] ,  m_rgb_color [ 1 ] ,  m_rgb_color [ 2 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-10 12:27:36 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-21 22:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  String : : formatted ( " \ e[{}m " ,  ( u8 ) m_xterm_color  +  40 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-10 12:27:36 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  Style : : Foreground : : to_vt_escape ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is_default ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-10 12:27:36 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_is_rgb )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-21 22:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  String : : formatted ( " \ e[38;2;{};{};{}m " ,  m_rgb_color [ 0 ] ,  m_rgb_color [ 1 ] ,  m_rgb_color [ 2 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-10 12:27:36 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-21 22:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  String : : formatted ( " \ e[{}m " ,  ( u8 ) m_xterm_color  +  30 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-10 12:27:36 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  Style : : Hyperlink : : to_vt_escape ( bool  starting )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-21 22:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  String : : formatted ( " \ e]8;;{} \ e \\ " ,  starting  ?  m_link  :  String : : empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Style : : unify_with ( const  Style &  other ,  bool  prefer_other )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Unify colors.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( prefer_other  | |  m_background . is_default ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_background  =  other . background ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( prefer_other  | |  m_foreground . is_default ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_foreground  =  other . foreground ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Unify graphic renditions.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( other . bold ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        set ( Bold ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( other . italic ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        set ( Italic ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( other . underline ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        set ( Underline ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Unify links.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( prefer_other  | |  m_hyperlink . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_hyperlink  =  other . hyperlink ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  Style : : to_string ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringBuilder  builder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    builder . append ( " Style {  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_foreground . is_default ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        builder . append ( " Foreground( " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_foreground . m_is_rgb )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            builder . join ( " ,  " ,  m_foreground . m_rgb_color ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 20:47:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            builder . appendff ( " (XtermColor) {} " ,  ( int ) m_foreground . m_xterm_color ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        builder . append ( " ),  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_background . is_default ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        builder . append ( " Background( " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_background . m_is_rgb )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            builder . join ( '   ' ,  m_background . m_rgb_color ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 20:47:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            builder . appendff ( " (XtermColor) {} " ,  ( int ) m_background . m_xterm_color ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        builder . append ( " ),  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( bold ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        builder . append ( " Bold,  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( underline ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        builder . append ( " Underline,  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( italic ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        builder . append ( " Italic,  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_hyperlink . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 20:47:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        builder . appendff ( " Hyperlink( \" {} \" ),  " ,  m_hyperlink . m_link ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    builder . append ( " } " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  builder . build ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  VT : : apply_style ( const  Style &  style ,  OutputStream &  stream ,  bool  is_starting )  
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is_starting )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        stream . write ( String : : formatted ( " \033 [{};{};{}m{}{}{} " , 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            style . bold ( )  ?  1  :  22 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            style . underline ( )  ?  4  :  24 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            style . italic ( )  ?  3  :  23 , 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            style . background ( ) . to_vt_escape ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            style . foreground ( ) . to_vt_escape ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            style . hyperlink ( ) . to_vt_escape ( true ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                         . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        stream . write ( style . hyperlink ( ) . to_vt_escape ( false ) . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  VT : : clear_lines ( size_t  count_above ,  size_t  count_below ,  OutputStream &  stream )  
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-02-21 04:37:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( count_below  +  count_above  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        stream . write ( " \033 [2K " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 04:37:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Go down count_below lines.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( count_below  >  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            stream . write ( String : : formatted ( " \033 [{}B " ,  count_below ) . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 04:37:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Then clear lines going upwards.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( size_t  i  =  count_below  +  count_above ;  i  >  0 ;  - - i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            stream . write ( " \033 [2K " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( i  ! =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                stream . write ( " \033 [A " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 04:37:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 06:41:33 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  VT : : save_cursor ( OutputStream &  stream )  
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    stream . write ( " \033 [s " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  VT : : restore_cursor ( OutputStream &  stream )  
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    stream . write ( " \033 [u " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  VT : : clear_to_end_of_line ( OutputStream &  stream )  
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-19 23:12:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    stream . write ( " \033 [K " sv . bytes ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 21:29:04 +04:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 01:47:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								StringMetrics  Editor : : actual_rendered_string_metrics ( const  StringView &  string )  
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    StringMetrics  metrics ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    StringMetrics : : LineMetrics  current_line ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VTState  state  {  Free  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Utf8View  view  {  string  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  it  =  view . begin ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( ;  it  ! =  view . end ( ) ;  + + it )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  c  =  * it ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  it_copy  =  it ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        + + it_copy ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  next_c  =  it_copy  = =  view . end ( )  ?  0  :  * it_copy ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        state  =  actual_rendered_string_length_step ( metrics ,  view . iterator_offset ( it ) ,  current_line ,  c ,  next_c ,  state ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    metrics . line_metrics . append ( current_line ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  line  :  metrics . line_metrics ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        metrics . max_line_length  =  max ( line . total_length ( ) ,  metrics . max_line_length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  metrics ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 01:47:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								StringMetrics  Editor : : actual_rendered_string_metrics ( const  Utf32View &  view )  
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringMetrics  metrics ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    StringMetrics : : LineMetrics  current_line ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VTState  state  {  Free  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  view . length ( ) ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  c  =  view . code_points ( ) [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  next_c  =  i  +  1  <  view . length ( )  ?  view . code_points ( ) [ i  +  1 ]  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        state  =  actual_rendered_string_length_step ( metrics ,  i ,  current_line ,  c ,  next_c ,  state ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    metrics . line_metrics . append ( current_line ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  line  :  metrics . line_metrics ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        metrics . max_line_length  =  max ( line . total_length ( ) ,  metrics . max_line_length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  metrics ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Editor : : VTState  Editor : : actual_rendered_string_length_step ( StringMetrics &  metrics ,  size_t  index ,  StringMetrics : : LineMetrics &  current_line ,  u32  c ,  u32  next_c ,  VTState  state )  
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( state )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Free : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( c  = =  ' \x1b ' )  {  // escape
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Escape ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( c  = =  ' \r ' )  {  // carriage return
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            current_line . masked_chars  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            current_line . length  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! metrics . line_metrics . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                metrics . line_metrics . last ( )  =  {  { } ,  0  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( c  = =  ' \n ' )  {  // return
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            metrics . line_metrics . append ( current_line ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            current_line . masked_chars  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            current_line . length  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  state ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is_ascii_control ( c )  & &  c  ! =  ' \n ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-13 12:58:06 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            current_line . masked_chars . append ( {  index ,  1 ,  c  <  64  ?  2u  :  4u  } ) ;  // if the character cannot be represented as ^c, represent it as \xbb.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: This will not support anything sophisticated
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        + + current_line . length ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        + + metrics . total_length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Escape : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( c  = =  ' ] ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( next_c  = =  ' 0 ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                state  =  Title ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( c  = =  ' [ ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Bracket ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: This does not support non-VT (aside from set-title) escapes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Bracket : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is_ascii_digit ( c ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  BracketArgsSemi ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  BracketArgsSemi : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( c  = =  ' ; ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Bracket ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! is_ascii_digit ( c ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            state  =  Free ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Title : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( c  = =  7 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            state  =  Free ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  state ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  state ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 06:10:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Result < Vector < size_t ,  2 > ,  Editor : : Error >  Editor : : vt_dsr ( )  
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-04-29 01:47:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    char  buf [ 16 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Read whatever junk there is before talking to the terminal
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // and insert them later when we're reading user input.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-29 01:47:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  more_junk_to_read  {  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    timeval  timeout  {  0 ,  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fd_set  readfds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    FD_ZERO ( & readfds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    FD_SET ( 0 ,  & readfds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        more_junk_to_read  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-20 16:09:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        [[maybe_unused]]  auto  rc  =  select ( 1 ,  & readfds ,  nullptr ,  nullptr ,  & timeout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-29 01:47:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( FD_ISSET ( 0 ,  & readfds ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-29 00:03:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  nread  =  read ( 0 ,  buf ,  16 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-25 16:57:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( nread  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_input_error  =  Error : : ReadFailure ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 15:04:39 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                finish ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-25 16:57:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( nread  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_incomplete_data . append ( buf ,  nread ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-29 01:47:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            more_junk_to_read  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  while  ( more_junk_to_read ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-25 16:57:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_input_error . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 06:10:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  m_input_error . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-25 16:57:07 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-09 19:31:15 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    fputs ( " \033 [6n " ,  stderr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fflush ( stderr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 22:48:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Parse the DSR response
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // it should be of the form .*\e[\d+;\d+R.*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Anything not part of the response is just added to the incomplete data.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Free , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        SawEsc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        SawBracket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        InFirstCoordinate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        SawSemicolon , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        InSecondCoordinate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        SawR , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  state  {  Free  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  has_error  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < char ,  4 >  coordinate_buffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  row  {  1  } ,  col  {  1  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    do  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 22:48:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        char  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  nread  =  read ( 0 ,  & c ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( nread  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 01:49:55 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( errno  = =  0  | |  errno  = =  EINTR )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 09:53:22 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // ????
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 21:13:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            dbgln ( " Error while reading DSR: {} " ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 06:10:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Error : : ReadFailure ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( nread  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-09 18:51:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            dbgln ( " Terminal DSR issue; received no response " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 06:10:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  Error : : Empty ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 22:48:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        switch  ( state )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  Free : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( c  = =  ' \x1b ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                state  =  SawEsc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_incomplete_data . append ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  SawEsc : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( c  = =  ' [ ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                state  =  SawBracket ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_incomplete_data . append ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  SawBracket : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is_ascii_digit ( c ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 22:48:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                state  =  InFirstCoordinate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                coordinate_buffer . append ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_incomplete_data . append ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  InFirstCoordinate : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is_ascii_digit ( c ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 22:48:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                coordinate_buffer . append ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( c  = =  ' ; ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  maybe_row  =  StringView  {  coordinate_buffer . data ( ) ,  coordinate_buffer . size ( )  } . to_uint ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! maybe_row . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    has_error  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                row  =  maybe_row . value_or ( 1u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                coordinate_buffer . clear_with_capacity ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                state  =  SawSemicolon ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_incomplete_data . append ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  SawSemicolon : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is_ascii_digit ( c ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 22:48:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                state  =  InSecondCoordinate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                coordinate_buffer . append ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_incomplete_data . append ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  InSecondCoordinate : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is_ascii_digit ( c ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 22:48:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                coordinate_buffer . append ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( c  = =  ' R ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  maybe_column  =  StringView  {  coordinate_buffer . data ( ) ,  coordinate_buffer . size ( )  } . to_uint ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! maybe_column . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    has_error  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                col  =  maybe_column . value_or ( 1u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                coordinate_buffer . clear_with_capacity ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                state  =  SawR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_incomplete_data . append ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  SawR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_incomplete_data . append ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-16 22:48:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  while  ( state  ! =  SawR ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( has_error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln ( " Terminal DSR issue, couldn't parse DSR response " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 06:10:10 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  Vector < size_t ,  2 >  {  row ,  col  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-09 07:44:04 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 08:42:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  Editor : : line ( size_t  up_to_index )  const  
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringBuilder  builder ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 08:42:01 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    builder . append ( Utf32View  {  m_buffer . data ( ) ,  min ( m_buffer . size ( ) ,  up_to_index )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 13:47:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  builder . build ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Editor : : remove_at_index ( size_t  index )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // See if we have any anchored styles, and reposition them if needed.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    readjust_anchored_styles ( index ,  ModificationKind : : Removal ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  cp  =  m_buffer [ index ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_buffer . remove ( index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( cp  = =  ' \n ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        + + m_extra_forward_lines ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    + + m_chars_touched_in_the_middle ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Editor : : readjust_anchored_styles ( size_t  hint_index ,  ModificationKind  modification )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  Anchor  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Span  old_span ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Span  new_span ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Style  style ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < Anchor >  anchors_to_relocate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  index_shift  =  modification  = =  ModificationKind : : Insertion  ?  1  :  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 05:14:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  forced_removal  =  modification  = =  ModificationKind : : ForcedOverlapRemoval ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  start_entry  :  m_current_spans . m_anchored_spans_starting )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  end_entry  :  start_entry . value )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 05:14:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( forced_removal )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 15:15:56 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( start_entry . key  < =  hint_index  & &  end_entry . key  >  hint_index )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    // Remove any overlapping regions.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 05:14:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( start_entry . key  > =  hint_index )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( start_entry . key  = =  hint_index  & &  end_entry . key  = =  hint_index  +  1  & &  modification  = =  ModificationKind : : Removal )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    // Remove the anchor, as all its text was wiped.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Shift everything.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                anchors_to_relocate . append ( {  {  start_entry . key ,  end_entry . key ,  Span : : Mode : : CodepointOriented  } ,  {  start_entry . key  +  index_shift ,  end_entry . key  +  index_shift ,  Span : : Mode : : CodepointOriented  } ,  end_entry . value  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( end_entry . key  >  hint_index )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Shift just the end.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                anchors_to_relocate . append ( {  {  start_entry . key ,  end_entry . key ,  Span : : Mode : : CodepointOriented  } ,  {  start_entry . key ,  end_entry . key  +  index_shift ,  Span : : Mode : : CodepointOriented  } ,  end_entry . value  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            anchors_to_relocate . append ( {  {  start_entry . key ,  end_entry . key ,  Span : : Mode : : CodepointOriented  } ,  {  start_entry . key ,  end_entry . key ,  Span : : Mode : : CodepointOriented  } ,  end_entry . value  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_current_spans . m_anchored_spans_ending . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_current_spans . m_anchored_spans_starting . clear ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-23 03:19:48 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Pass over the relocations and update the stale entries.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 02:25:58 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  relocation  :  anchors_to_relocate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        stylize ( relocation . new_span ,  relocation . style ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-29 20:08:02 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								size_t  StringMetrics : : lines_with_addition ( const  StringMetrics &  offset ,  size_t  column_width )  const  
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  lines  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  line_metrics . size ( )  -  1 ;  + + i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lines  + =  ( line_metrics [ i ] . total_length ( )  +  column_width )  /  column_width ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  last  =  line_metrics . last ( ) . total_length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    last  + =  offset . line_metrics . first ( ) . total_length ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    lines  + =  ( last  +  column_width )  /  column_width ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( size_t  i  =  1 ;  i  <  offset . line_metrics . size ( ) ;  + + i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lines  + =  ( offset . line_metrics [ i ] . total_length ( )  +  column_width )  /  column_width ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 16:43:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  lines ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								size_t  StringMetrics : : offset_with_addition ( const  StringMetrics &  offset ,  size_t  column_width )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( offset . line_metrics . size ( )  >  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  offset . line_metrics . last ( ) . total_length ( )  %  column_width ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-10 16:23:04 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  last  =  line_metrics . last ( ) . total_length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    last  + =  offset . line_metrics . first ( ) . total_length ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-04 11:38:56 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  last  %  column_width ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-20 21:33:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Editor : : Spans : : contains_up_to_offset ( const  Spans &  other ,  size_t  offset )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  compare  =  [ & ] < typename  K ,  typename  V > ( const  HashMap < K ,  HashMap < K ,  V > > &  left ,  const  HashMap < K ,  HashMap < K ,  V > > &  right )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  entry  :  right )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( entry . key  >  offset  +  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  left_map  =  left . get ( entry . key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! left_map . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  left_entry  :  left_map . value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( auto  value  =  entry . value . get ( left_entry . key ) ;  ! value . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Might have the same thing with a longer span
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    bool  found  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    for  ( auto &  possibly_longer_span_entry  :  entry . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( possibly_longer_span_entry . key  >  left_entry . key  & &  possibly_longer_span_entry . key  >  offset  & &  left_entry . value  = =  possibly_longer_span_entry . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            found  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( found ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  constexpr  ( LINE_EDITOR_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        dbgln ( " Compare for {}-{} failed, no entry " ,  entry . key ,  left_entry . key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        for  ( auto &  x  :  entry . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            dbgln ( " Have: {}-{} = {} " ,  entry . key ,  x . key ,  x . value . to_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( value . value ( )  ! =  left_entry . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    dbgln_if ( LINE_EDITOR_DEBUG ,  " Compare for {}-{} failed, different values: {} != {} " ,  entry . key ,  left_entry . key ,  value . value ( ) . to_string ( ) ,  left_entry . value . to_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  compare ( m_spans_starting ,  other . m_spans_starting ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        & &  compare ( m_anchored_spans_starting ,  other . m_anchored_spans_starting ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 13:34:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}