svn commit: branches/busybox_1_00_stable/busybox/editors

andersen at busybox.net andersen at busybox.net
Mon Sep 12 22:20:24 UTC 2005


Author: andersen
Date: 2005-09-12 15:20:22 -0700 (Mon, 12 Sep 2005)
New Revision: 11434

Log:
Patch from Paul Fox to fix the reported vi status line problems.

Paul writes:

the bugs were being caused because when edit_status() and/or
show_status_line() were being called, the current status wasn't
always yet up to date.  i've changed things so that the
formatting/checking/displaying of the status line occurs more
rigorously as the last thing before the user is asked for input.
i did some minor optimization so we don't have to count the
file's lines every time, but this could be improved.  (yes, i
know that turning file_modified into a counter will cause it to
be wrong once in blue moon.  i'm willing to risk that.  ymmv.
this could be fixed with the addition of one more boolean.)



Modified:
   branches/busybox_1_00_stable/busybox/editors/vi.c


Changeset:
Modified: branches/busybox_1_00_stable/busybox/editors/vi.c
===================================================================
--- branches/busybox_1_00_stable/busybox/editors/vi.c	2005-09-12 21:42:48 UTC (rev 11433)
+++ branches/busybox_1_00_stable/busybox/editors/vi.c	2005-09-12 22:20:22 UTC (rev 11434)
@@ -166,7 +166,7 @@
 
 
 static int editing;		// >0 while we are editing a file
-static int cmd_mode;		// 0=command  1=insert
+static int cmd_mode;		// 0=command  1=insert 2=replace
 static int file_modified;	// buffer contents changed
 static int fn_start;		// index of first cmd line file name
 static int save_argc;		// how many file names on cmd line
@@ -272,7 +272,7 @@
 static void psb(const char *, ...);     // Print Status Buf
 static void psbs(const char *, ...);    // Print Status Buf in standout mode
 static void ni(Byte *);		// display messages
-static void edit_status(void);	// show file status on status line
+static void compute_edit_status(void);	// format file status on status line
 static void redraw(int);	// force a full screen refresh
 static void format_line(Byte*, Byte*, int);
 static void refresh(int);	// update the terminal from screen[]
@@ -450,7 +450,7 @@
 	if (ch < 1) {
 		(void) char_insert(text, '\n');	// start empty buf with dummy line
 	}
-	file_modified = FALSE;
+	file_modified = 0;
 #ifdef CONFIG_FEATURE_VI_YANKMARK
 	YDreg = 26;			// default Yank/Delete reg
 	Ureg = 27;			// hold orig line for "U" cmd
@@ -506,7 +506,6 @@
 	adding2q = 0;
 #endif							/* CONFIG_FEATURE_VI_DOT_CMD */
 	redraw(FALSE);			// dont force every col re-draw
-	edit_status();
 	show_status_line();
 
 	//------This is the main Vi cmd handling loop -----------------------
@@ -834,7 +833,7 @@
 			(void) char_insert(text, '\n');
 			ch= 1;
 		}
-		file_modified = FALSE;
+		file_modified = 0;
 #ifdef CONFIG_FEATURE_VI_YANKMARK
 		if (Ureg >= 0 && Ureg < 28 && reg[Ureg] != 0) {
 			free(reg[Ureg]);	//   free orig line reg- for 'U'
@@ -871,8 +870,7 @@
 			cfn = (Byte *) bb_xstrdup((char *) args);
 		} else {
 			// user wants file status info
-			edit_status();
-			show_status_line();
+			/* no-op */;
 		}
 	} else if (strncasecmp((char *) cmd, "features", i) == 0) {	// what features are available
 		// print out values of all features
@@ -978,7 +976,7 @@
 			// if the insert is before "dot" then we need to update
 			if (q <= dot)
 				dot += ch;
-			file_modified = TRUE;
+			file_modified++;
 		}
 	} else if (strncasecmp((char *) cmd, "rewind", i) == 0) {	// rewind cmd line args
 		if (file_modified && ! useforce) {
@@ -1110,7 +1108,7 @@
 		}
 		psb("\"%s\" %dL, %dC", fn, li, l);
 		if (q == text && r == end - 1 && l == ch)
-			file_modified = FALSE;
+			file_modified = 0;
 		if ((cmd[0] == 'x' || cmd[1] == 'q') && l == ch) {
 			editing = 0;
 		}
@@ -1335,30 +1333,22 @@
 {
 	if (dot > text && dot[-1] != '\n')
 		dot--;
-	edit_status();			// show current file status
-	show_status_line();
 }
 
 static void dot_right(void)
 {
 	if (dot < end - 1 && *dot != '\n')
 		dot++;
-	edit_status();			// show current file status
-	show_status_line();
 }
 
 static void dot_begin(void)
 {
 	dot = begin_line(dot);	// return pointer to first char cur line
-	edit_status();			// show current file status
-	show_status_line();
 }
 
 static void dot_end(void)
 {
 	dot = end_line(dot);	// return pointer to last char cur line
-	edit_status();			// show current file status
-	show_status_line();
 }
 
 static Byte *move_to_col(Byte * p, int l)
@@ -1383,15 +1373,11 @@
 static void dot_next(void)
 {
 	dot = next_line(dot);
-	edit_status();			// show current file status
-	show_status_line();
 }
 
 static void dot_prev(void)
 {
 	dot = prev_line(dot);
-	edit_status();			// show current file status
-	show_status_line();
 }
 
 static void dot_scroll(int cnt, int dir)
@@ -1416,8 +1402,6 @@
 	if (dot > q)
 		dot = begin_line(q);	// is dot is below bottom line?
 	dot_skip_over_ws();
-	edit_status();			// show current file status
-	show_status_line();
 }
 
 static void dot_skip_over_ws(void)
@@ -1603,7 +1587,7 @@
 		c = get_one_char();
 		*p = c;
 		p++;
-		file_modified = TRUE;	// has the file been modified
+		file_modified++;	// has the file been modified
 	} else if (c == 27) {	// Is this an ESC?
 		cmd_mode = 0;
 		cmdcnt = 0;
@@ -1658,7 +1642,7 @@
 	p = text_hole_make(p, 1);
 	if (p != 0) {
 		*p = c;
-		file_modified = TRUE;	// has the file been modified
+		file_modified++;	// has the file been modified
 		p++;
 	}
 	return (p);
@@ -1856,7 +1840,7 @@
 	}
 	memset(p, ' ', size);	// clear new hole
 	end = end + size;	// adjust the new END
-	file_modified = TRUE;	// has the file been modified
+	file_modified++;	// has the file been modified
   thm0:
 	return (p);
 }
@@ -1892,7 +1876,7 @@
 		dest = end - 1;	// make sure dest in below end-1
 	if (end <= text)
 		dest = end = text;	// keep pointers valid
-	file_modified = TRUE;	// has the file been modified
+	file_modified++;	// has the file been modified
   thd0:
 	return (dest);
 }
@@ -2511,7 +2495,7 @@
 		psbs("could not read all of file \"%s\"", fn);
 	}
 	if (cnt >= size)
-		file_modified = TRUE;
+		file_modified++;
   fi0:
 	return (cnt);
 }
@@ -2675,7 +2659,7 @@
 	static int last_cksum;
 	int l, cnt, cksum;
 
-	//edit_status();
+	compute_edit_status();
 	cnt = strlen((char *) status_buffer);
 	for (cksum= l= 0; l < cnt; l++) { cksum += (int)(status_buffer[l]); }
 	// don't write the status line unless it changes
@@ -2700,7 +2684,6 @@
 	vsprintf((char *) status_buffer + strlen((char *) status_buffer), format, args);
 	strcat((char *) status_buffer, SOn);	// Terminal standout mode off
 	va_end(args);
-	show_status_line();
 
 	return;
 }
@@ -2713,7 +2696,6 @@
 	va_start(args, format);
 	vsprintf((char *) status_buffer, format, args);
 	va_end(args);
-	show_status_line();
 	return;
 }
 
@@ -2725,12 +2707,19 @@
 	psbs("\'%s\' is not implemented", buf);
 }
 
-static void edit_status(void)	// show file status on status line
+static void compute_edit_status(void)	// show file status on status line
 {
-	int cur, tot, percent;
+	int cur, percent;
+	static int tot;
+	static int last_file_modified = -1;
 
 	cur = count_lines(text, dot);
-	tot = count_lines(text, end - 1);
+
+	/* try and reduce counting */
+	if (file_modified != last_file_modified) {
+		tot = cur + count_lines(dot, end - 1) - 1;
+		last_file_modified = file_modified;
+	}
 	//    current line         percent
 	//   -------------    ~~ ----------
 	//    total lines            100
@@ -2746,11 +2735,13 @@
 #ifdef CONFIG_FEATURE_VI_READONLY
 			"%s"
 #endif							/* CONFIG_FEATURE_VI_READONLY */
+			"%s"
 			"%s line %d of %d --%d%%--",
 			(cfn != 0 ? (char *) cfn : "No file"),
 #ifdef CONFIG_FEATURE_VI_READONLY
 			((vi_readonly || readonly) ? " [Read only]" : ""),
 #endif							/* CONFIG_FEATURE_VI_READONLY */
+			(cmd_mode ? (cmd_mode == 2 ? " [Replace]":" [Insert]") : ""),
 			(file_modified ? " [modified]" : ""),
 			cur, tot, percent);
 }
@@ -2898,8 +2889,6 @@
 #endif							/* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
 			}
 
-			edit_status();			// show current file status
-			show_status_line();
 			// write line out to terminal
 			{
 				int nic = ce-cs+1;
@@ -2959,6 +2948,8 @@
 	p = q = save_dot = msg = buf;	// quiet the compiler
 	memset(buf, '\0', 9);	// clear buf
 
+	show_status_line();
+
 	/* if this is a cursor key, skip these checks */
 	switch (c) {
 		case VI_K_UP:
@@ -3078,8 +3069,6 @@
 		dot_scroll(rows - 2, 1);
 		break;
 	case 7:			// ctrl-G  show current status
-		edit_status();
-		show_status_line();
 		break;
 	case 'h':			// h- move left
 	case VI_K_LEFT:	// cursor key Left
@@ -3089,8 +3078,6 @@
 			do_cmd(c);
 		}				// repeat cnt
 		dot_left();
-		edit_status();			// show current file status
-		show_status_line();
 		break;
 	case 10:			// Newline ^J
 	case 'j':			// j- goto next line, same col
@@ -3400,14 +3387,13 @@
 				   strncasecmp((char *) p, "wq", cnt) == 0 ||
 				   strncasecmp((char *) p, "x", cnt) == 0) {
 			cnt = file_write(cfn, text, end - 1);
-			file_modified = FALSE;
+			file_modified = 0;
 			psb("\"%s\" %dL, %dC", cfn, count_lines(text, end - 1), cnt);
 			if (p[0] == 'x' || p[1] == 'q') {
 				editing = 0;
 			}
 		} else if (strncasecmp((char *) p, "file", cnt) == 0 ) {
-			edit_status();			// show current file status
-			show_status_line();
+			/* no-op */;		// show current file status
 		} else if (sscanf((char *) p, "%d", &j) > 0) {
 			dot = find_line(j);		// go to line # j
 			dot_skip_over_ws();
@@ -3508,7 +3494,6 @@
 	case VI_K_INSERT:	// Cursor Key Insert
 	  dc_i:
 		cmd_mode = 1;	// start insrting
-		psb("-- Insert --");
 		break;
 	case 'J':			// J- join current and next lines together
 		if (cmdcnt-- > 2) {
@@ -3517,7 +3502,7 @@
 		dot_end();		// move to NL
 		if (dot < end - 1) {	// make sure not last char in text[]
 			*dot++ = ' ';	// replace NL with space
-			file_modified = TRUE;
+			file_modified++;
 			while (isblnk(*dot)) {	// delete leading WS
 				dot_delete();
 			}
@@ -3558,7 +3543,6 @@
 	case 'R':			// R- continuous Replace char
 	  dc5:
 		cmd_mode = 2;
-		psb("-- Replace --");
 		break;
 	case 'X':			// X- delete char before dot
 	case 'x':			// x- delete the current char
@@ -3708,7 +3692,7 @@
 		c1 = get_one_char();	// get the replacement char
 		if (*dot != '\n') {
 			*dot = c1;
-			file_modified = TRUE;	// has the file been modified
+			file_modified++;	// has the file been modified
 		}
 		end_cmd_q();	// stop adding to q
 		break;
@@ -3753,10 +3737,10 @@
 		}				// repeat cnt
 		if (islower(*dot)) {
 			*dot = toupper(*dot);
-			file_modified = TRUE;	// has the file been modified
+			file_modified++;	// has the file been modified
 		} else if (isupper(*dot)) {
 			*dot = tolower(*dot);
-			file_modified = TRUE;	// has the file been modified
+			file_modified++;	// has the file been modified
 		}
 		dot_right();
 		end_cmd_q();	// stop adding to q




More information about the busybox-cvs mailing list