vi: correct autoindent for 'O' command
Opening a line above the current line with the 'O' command should use the current, not previous, line to determine how much to autoindent. function old new delta char_insert 531 563 +32 do_cmd 4746 4723 -23 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 32/-23) Total: 9 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
		
				
					committed by
					
						
						Denys Vlasenko
					
				
			
			
				
	
			
			
			
						parent
						
							ac6495f6fb
						
					
				
				
					commit
					47c3eaa22f
				
			
							
								
								
									
										41
									
								
								editors/vi.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								editors/vi.c
									
									
									
									
									
								
							@@ -286,6 +286,7 @@ struct globals {
 | 
			
		||||
	int text_size;		// size of the allocated buffer
 | 
			
		||||
 | 
			
		||||
	// the rest
 | 
			
		||||
#if ENABLE_FEATURE_VI_SETOPTS
 | 
			
		||||
	smallint vi_setops;     // set by setops()
 | 
			
		||||
#define VI_AUTOINDENT (1 << 0)
 | 
			
		||||
#define VI_ERR_METHOD (1 << 1)
 | 
			
		||||
@@ -296,6 +297,7 @@ struct globals {
 | 
			
		||||
#define err_method (vi_setops & VI_ERR_METHOD) // indicate error with beep or flash
 | 
			
		||||
#define ignorecase (vi_setops & VI_IGNORECASE)
 | 
			
		||||
#define showmatch  (vi_setops & VI_SHOWMATCH )
 | 
			
		||||
#define openabove  (vi_setops & VI_TABSTOP   )
 | 
			
		||||
// order of constants and strings must match
 | 
			
		||||
#define OPTS_STR \
 | 
			
		||||
		"ai\0""autoindent\0" \
 | 
			
		||||
@@ -303,6 +305,15 @@ struct globals {
 | 
			
		||||
		"ic\0""ignorecase\0" \
 | 
			
		||||
		"sm\0""showmatch\0" \
 | 
			
		||||
		"ts\0""tabstop\0"
 | 
			
		||||
#define set_openabove() (vi_setops |= VI_TABSTOP)
 | 
			
		||||
#define clear_openabove() (vi_setops &= ~VI_TABSTOP)
 | 
			
		||||
#else
 | 
			
		||||
#define autoindent (0)
 | 
			
		||||
#define err_method (0)
 | 
			
		||||
#define openabove  (0)
 | 
			
		||||
#define set_openabove() ((void)0)
 | 
			
		||||
#define clear_openabove() ((void)0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLE_FEATURE_VI_READONLY
 | 
			
		||||
	smallint readonly_mode;
 | 
			
		||||
@@ -2130,8 +2141,13 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
 | 
			
		||||
			showmatching(p - 1);
 | 
			
		||||
		}
 | 
			
		||||
		if (autoindent && c == '\n') {	// auto indent the new line
 | 
			
		||||
			q = prev_line(p);	// use prev line as template
 | 
			
		||||
			// use current/previous line as template
 | 
			
		||||
			q = openabove ? p : prev_line(p);
 | 
			
		||||
			len = strspn(q, " \t"); // space or tab
 | 
			
		||||
			if (openabove) {
 | 
			
		||||
				p--;		// this replaces dot_prev() in do_cmd()
 | 
			
		||||
				q += len;	// template will be shifted by text_hole_make()
 | 
			
		||||
			}
 | 
			
		||||
			if (len) {
 | 
			
		||||
				uintptr_t bias;
 | 
			
		||||
				bias = text_hole_make(p, len);
 | 
			
		||||
@@ -2445,6 +2461,7 @@ static void setops(char *args, int flg_no)
 | 
			
		||||
	index = 1 << (index >> 1); // convert to VI_bit
 | 
			
		||||
 | 
			
		||||
	if (index & VI_TABSTOP) {
 | 
			
		||||
		// don't set this bit in vi_setops, it's reused as 'openabove'
 | 
			
		||||
		int t;
 | 
			
		||||
		if (!eq || flg_no) // no "=NNN" or it is "notabstop"?
 | 
			
		||||
			goto bad;
 | 
			
		||||
@@ -3841,19 +3858,19 @@ static void do_cmd(int c)
 | 
			
		||||
			dot = next_line(dot);
 | 
			
		||||
		dot_skip_over_ws();
 | 
			
		||||
		break;
 | 
			
		||||
	case 'O':			// O- open a empty line above
 | 
			
		||||
		//    0i\n ESC -i
 | 
			
		||||
		p = begin_line(dot);
 | 
			
		||||
		if (p[-1] == '\n') {
 | 
			
		||||
	case 'O':			// O- open an empty line above
 | 
			
		||||
		dot_begin();
 | 
			
		||||
		set_openabove();
 | 
			
		||||
		goto dc3;
 | 
			
		||||
	case 'o':			// o- open an empty line below
 | 
			
		||||
		dot_end();
 | 
			
		||||
 dc3:
 | 
			
		||||
		dot = char_insert(dot, '\n', ALLOW_UNDO);
 | 
			
		||||
		if (c == 'O' && !autoindent) {
 | 
			
		||||
			// done in char_insert() for openabove+autoindent
 | 
			
		||||
			dot_prev();
 | 
			
		||||
	case 'o':			// o- open a empty line below; Yes, I know it is in the middle of the "if (..."
 | 
			
		||||
			dot_end();
 | 
			
		||||
			dot = char_insert(dot, '\n', ALLOW_UNDO);
 | 
			
		||||
		} else {
 | 
			
		||||
			dot_begin();	// 0
 | 
			
		||||
			dot = char_insert(dot, '\n', ALLOW_UNDO);	// i\n ESC
 | 
			
		||||
			dot_prev();	// -
 | 
			
		||||
		}
 | 
			
		||||
		clear_openabove();
 | 
			
		||||
		goto dc_i;
 | 
			
		||||
		break;
 | 
			
		||||
	case 'R':			// R- continuous Replace char
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user