vi: make de-indentation with ctrl-D more like vim
Commit ac6495f6f (vi: allow ctrl-D to reduce indentation) treated
ctrl-D during autoindent as a backspace.  This was adequate for
indentation using tabs but doesn't work well with the expandtab
option.  In the latter case it's necessary to backspace over all
the spaces.
Make ctrl-D work correctly when spaces are present in the indent.
Also, make it behave more like vim:
- ctrl-D is independent of autoindent;
- indentation is reduced even when the cursor isn't positioned at
  the end of the indent.
function                                             old     new   delta
char_insert                                          679     717     +38
get_column                                             -      37     +37
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 75/0)               Total: 75 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
						Denys Vlasenko
					
				
			
			
				
	
			
			
			
						parent
						
							310ef23280
						
					
				
				
					commit
					f277c9eebb
				
			
							
								
								
									
										30
									
								
								editors/vi.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								editors/vi.c
									
									
									
									
									
								
							| @@ -763,6 +763,11 @@ static int next_tabstop(int col) | ||||
| 	return col + ((tabstop - 1) - (col % tabstop)); | ||||
| } | ||||
|  | ||||
| static int prev_tabstop(int col) | ||||
| { | ||||
| 	return col - ((col % tabstop) ?: tabstop); | ||||
| } | ||||
|  | ||||
| static int next_column(char c, int co) | ||||
| { | ||||
| 	if (c == '\t') | ||||
| @@ -772,7 +777,6 @@ static int next_column(char c, int co) | ||||
| 	return co + 1; | ||||
| } | ||||
|  | ||||
| #if ENABLE_FEATURE_VI_SETOPTS | ||||
| static int get_column(char *p) | ||||
| { | ||||
| 	const char *r; | ||||
| @@ -782,7 +786,6 @@ static int get_column(char *p) | ||||
| 		co = next_column(*r, co); | ||||
| 	return co; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| //----- Erase the Screen[] memory ------------------------------ | ||||
| static void screen_erase(void) | ||||
| @@ -2113,14 +2116,23 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' | ||||
| 		if ((p[-1] != '\n') && (dot > text)) { | ||||
| 			p--; | ||||
| 		} | ||||
| #if ENABLE_FEATURE_VI_SETOPTS | ||||
| 	} else if (c == 4 && autoindent) {	// ctrl-D reduces indentation | ||||
| 		q = begin_line(p); | ||||
| 		len = strspn(q, " \t"); | ||||
| 		if (len && q + len == p) { | ||||
| 			p--; | ||||
| 			p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); | ||||
| 	} else if (c == 4) {	// ctrl-D reduces indentation | ||||
| 		int prev; | ||||
| 		char *r, *bol; | ||||
| 		bol = begin_line(p); | ||||
| 		for (r = bol; r < end_line(p); ++r) { | ||||
| 			if (!isblank(*r)) | ||||
| 				break; | ||||
| 		} | ||||
|  | ||||
| 		prev = prev_tabstop(get_column(r)); | ||||
| 		while (r > bol && get_column(r) > prev) { | ||||
| 			if (p > bol) | ||||
| 				p--; | ||||
| 			r--; | ||||
| 			r = text_hole_delete(r, r, ALLOW_UNDO_QUEUED); | ||||
| 		} | ||||
| #if ENABLE_FEATURE_VI_SETOPTS | ||||
| 	} else if (c == '\t' && expandtab) {	// expand tab | ||||
| 		int col = get_column(p); | ||||
| 		col = next_tabstop(col) - col + 1; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user