changeset 12204:b49b03085f39 v8.0.0982

patch 8.0.0982: cannot use a terminal when 'encoding' is non-utf8 multi-byte commit https://github.com/vim/vim/commit/740c433c5909e3118dc4a7c42028f8a8b78a353b Author: Bram Moolenaar <Bram@vim.org> Date: Mon Aug 21 22:01:27 2017 +0200 patch 8.0.0982: cannot use a terminal when 'encoding' is non-utf8 multi-byte Problem: When 'encoding' is set to a multi-byte encoding other than utf-8 the characters from ther terminal are messed up. Solution: Convert displayed text from utf-8 to 'encoding' for MS-Windows. (Yasuhiro Matsumoto, close #2000)
author Christian Brabandt <cb@256bit.org>
date Mon, 21 Aug 2017 22:15:05 +0200
parents fb4032c4535f
children 85c43ec066d8
files src/terminal.c src/version.c
diffstat 2 files changed, 68 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -49,8 +49,8 @@
 	"err_io", "err_name", "err_buf", "err_modifiable", "err_msg"
  *   Check that something is connected to the terminal.
  *   Test: "cat" reading from a file or buffer
- *         "ls" writing stdout to a file or buffer
- *         shell writing stderr to a file or buffer
+ *	   "ls" writing stdout to a file or buffer
+ *	   shell writing stderr to a file or buffer
  * - For the GUI fill termios with default values, perhaps like pangoterm:
  *   http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
  * - support ":term NONE" to open a terminal with a pty but not running a job
@@ -845,7 +845,26 @@ add_scrollback_line_to_buffer(term_T *te
     int		empty = (buf->b_ml.ml_flags & ML_EMPTY);
     linenr_T	lnum = buf->b_ml.ml_line_count;
 
-    ml_append_buf(term->tl_buffer, lnum, text, len + 1, FALSE);
+#ifdef _WIN32
+    if (!enc_utf8 && enc_codepage > 0)
+    {
+	WCHAR   *ret = NULL;
+	int	length = 0;
+
+	MultiByteToWideChar_alloc(CP_UTF8, 0, (char*)text, len + 1,
+							   &ret, &length);
+	if (ret != NULL)
+	{
+	    WideCharToMultiByte_alloc(enc_codepage, 0,
+				      ret, length, (char **)&text, &len, 0, 0);
+	    vim_free(ret);
+	    ml_append_buf(term->tl_buffer, lnum, text, len, FALSE);
+	    vim_free(text);
+	}
+    }
+    else
+#endif
+	ml_append_buf(term->tl_buffer, lnum, text, len + 1, FALSE);
     if (empty)
     {
 	/* Delete the empty line that was in the empty buffer. */
@@ -936,7 +955,7 @@ move_terminal_to_buffer(term_T *term)
 			    int	    c;
 
 			    for (i = 0; (c = cell.chars[i]) > 0 || i == 0; ++i)
-				ga.ga_len += mb_char2bytes(c == NUL ? ' ' : c,
+				ga.ga_len += utf_char2bytes(c == NUL ? ' ' : c,
 					     (char_u *)ga.ga_data + ga.ga_len);
 			}
 		    }
@@ -1468,6 +1487,18 @@ terminal_loop(void)
 		goto theend;
 	    }
 	}
+# ifdef _WIN32
+	if (!enc_utf8 && has_mbyte && c >= 0x80)
+	{
+	    WCHAR   wc;
+	    char_u  mb[3];
+
+	    mb[0] = (unsigned)c >> 8;
+	    mb[1] = c;
+	    if (MultiByteToWideChar(GetACP(), 0, (char*)mb, 2, &wc, 1) > 0)
+		c = wc;
+	}
+# endif
 	if (send_keys_to_term(curbuf->b_term, c, TRUE) != OK)
 	{
 	    ret = OK;
@@ -1627,7 +1658,7 @@ color2index(VTermColor *color, int fg, i
 
 	/* 216-color cube */
 	return 17 + ((red + 25) / 0x33) * 36
-	          + ((green + 25) / 0x33) * 6
+		  + ((green + 25) / 0x33) * 6
 		  + (blue + 25) / 0x33;
     }
     return 0;
@@ -2076,20 +2107,39 @@ term_update_window(win_T *wp)
 		else
 		{
 #if defined(FEAT_MBYTE)
-		    if (enc_utf8 && c >= 0x80)
+		    if (enc_utf8)
 		    {
-			ScreenLines[off] = ' ';
-			ScreenLinesUC[off] = c;
+			if (c >= 0x80)
+			{
+			    ScreenLines[off] = ' ';
+			    ScreenLinesUC[off] = c;
+			}
+			else
+			{
+			    ScreenLines[off] = c;
+			    ScreenLinesUC[off] = NUL;
+			}
 		    }
-		    else
+# ifdef _WIN32
+		    else if (has_mbyte && c >= 0x80)
 		    {
-			ScreenLines[off] = c;
-			if (enc_utf8)
-			    ScreenLinesUC[off] = NUL;
+			char_u	mb[MB_MAXBYTES+1];
+			WCHAR	wc = c;
+
+			if (WideCharToMultiByte(GetACP(), 0, &wc, 1,
+						       (char*)mb, 2, 0, 0) > 1)
+			{
+			    ScreenLines[off] = mb[0];
+			    ScreenLines[off+1] = mb[1];
+			    cell.width = mb_ptr2cells(mb);
+			}
+			else
+			    ScreenLines[off] = c;
 		    }
-#else
-		    ScreenLines[off] = c;
+# endif
+		    else
 #endif
+			ScreenLines[off] = c;
 		}
 		ScreenAttrs[off] = cell2attr(cell.attrs, cell.fg, cell.bg);
 
@@ -2097,11 +2147,12 @@ term_update_window(win_T *wp)
 		++off;
 		if (cell.width == 2)
 		{
-		    ScreenLines[off] = NUL;
 #if defined(FEAT_MBYTE)
 		    if (enc_utf8)
 			ScreenLinesUC[off] = NUL;
+		    else if (!has_mbyte)
 #endif
+			ScreenLines[off] = NUL;
 		    ++pos.col;
 		    ++off;
 		}
--- a/src/version.c
+++ b/src/version.c
@@ -770,6 +770,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    982,
+/**/
     981,
 /**/
     980,