[PATCH 2/2] vi: don't touch file with :x when modified_count == 0

Yousong Zhou yszhou4tech at gmail.com
Wed Feb 22 13:11:52 UTC 2017


Along with it, there are other changes

 - Check for uppercase X is removed as the expression will be always false and
   :X itself is another totally different command in standard vim
 - The status line will show number of written lines instead of lines requested
   by the colon command.  This is also how the standard vim is doing, though
   the difference is that '!' has to be explicitly specified in vim to allow
   partial writes

"make bloatcheck" output

    function                                             old     new   delta
    colon                                               3190    3193      +3
    ------------------------------------------------------------------------------
    (add/remove: 0/0 grow/shrink: 1/0 up/down: 3/0)                 Total: 3 bytes

Signed-off-by: Yousong Zhou <yszhou4tech at gmail.com>
---
 editors/vi.c | 43 ++++++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 17 deletions(-)

diff --git a/editors/vi.c b/editors/vi.c
index 4b5b7cd..f33db66 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -1034,7 +1034,9 @@ static void colon(char *buf)
 	 || strncmp(p, "wn", cnt) == 0
 	 || (p[0] == 'x' && !p[1])
 	) {
-		cnt = file_write(current_filename, text, end - 1);
+		if (modified_count != 0 || p[0] != 'x') {
+			cnt = file_write(current_filename, text, end - 1);
+		}
 		if (cnt < 0) {
 			if (cnt == -1)
 				status_line_bold("Write error: %s", strerror(errno));
@@ -1045,8 +1047,9 @@ static void colon(char *buf)
 				current_filename,
 				count_lines(text, end - 1), cnt
 			);
-			if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
-			 || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
+			if (p[0] == 'x'
+			 || p[1] == 'q' || p[1] == 'n'
+			 || p[1] == 'Q' || p[1] == 'N'
 			) {
 				editing = 0;
 			}
@@ -1476,16 +1479,19 @@ static void colon(char *buf)
 			goto ret;
 		}
 #endif
-		// how many lines in text[]?
-		li = count_lines(q, r);
-		size = r - q + 1;
 		//if (useforce) {
 			// if "fn" is not write-able, chmod u+w
 			// sprintf(syscmd, "chmod u+w %s", fn);
 			// system(syscmd);
 			// forced = TRUE;
 		//}
-		l = file_write(fn, q, r);
+		if (modified_count != 0 || cmd[0] != 'x') {
+			size = r - q + 1;
+			l = file_write(fn, q, r);
+		} else {
+			size = 0;
+			l = 0;
+		}
 		//if (useforce && forced) {
 			// chmod u-w
 			// sprintf(syscmd, "chmod u-w %s", fn);
@@ -1496,17 +1502,20 @@ static void colon(char *buf)
 			if (l == -1)
 				status_line_bold_errno(fn);
 		} else {
+			// how many lines written
+			li = count_lines(q, q + l - 1);
 			status_line("'%s' %dL, %dC", fn, li, l);
-			if (q == text && r == end - 1 && l == size) {
-				modified_count = 0;
-				last_modified_count = -1;
-			}
-			if ((cmd[0] == 'x' || cmd[1] == 'q' || cmd[1] == 'n'
-			    || cmd[0] == 'X' || cmd[1] == 'Q' || cmd[1] == 'N'
-			    )
-			 && l == size
-			) {
-				editing = 0;
+			if (l == size) {
+				if (q == text && q + l == end) {
+					modified_count = 0;
+					last_modified_count = -1;
+				}
+				if (cmd[0] == 'x'
+				 || cmd[1] == 'q' || cmd[1] == 'n'
+				 || cmd[1] == 'Q' || cmd[1] == 'N'
+				) {
+					editing = 0;
+				}
 			}
 		}
 #if ENABLE_FEATURE_VI_YANKMARK
-- 
2.6.4



More information about the busybox mailing list