# HG changeset patch # User Bram Moolenaar # Date 1550150115 -3600 # Node ID 9745c25da3bc566996466a007383c1140e045aa7 # Parent 1c1897fe1cc2db603accaede130138ece898bee1 patch 8.1.0918: MS-Windows: startup messages are not converted commit https://github.com/vim/vim/commit/9b5c1fcdeae75f82a2083fafbbf75ab220f6ac1e Author: Bram Moolenaar Date: Thu Feb 14 14:08:04 2019 +0100 patch 8.1.0918: MS-Windows: startup messages are not converted Problem: MS-Windows: startup messages are not converted. Solution: Convert messages when the current codepage differs from 'encoding'. (Yasuhiro Matsumoto, closes #3914) diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -2570,57 +2570,45 @@ msg_use_printf(void) msg_puts_printf(char_u *str, int maxlen) { char_u *s = str; - char_u buf[4]; - char_u *p; + char_u *buf = NULL; + char_u *p = s; + #ifdef WIN3264 -# if !defined(FEAT_GUI_MSWIN) - char_u *ccp = NULL; - -# endif if (!(silent_mode && p_verbose == 0)) - mch_settmode(TMODE_COOK); /* handle '\r' and '\n' correctly */ - -# if !defined(FEAT_GUI_MSWIN) - if (enc_codepage >= 0 && (int)GetConsoleCP() != enc_codepage) - { - int inlen = (int)STRLEN(str); - int outlen; - WCHAR *widestr = (WCHAR *)enc_to_utf16(str, &inlen); - - if (widestr != NULL) - { - WideCharToMultiByte_alloc(GetConsoleCP(), 0, widestr, inlen, - (LPSTR *)&ccp, &outlen, 0, 0); - vim_free(widestr); - s = str = ccp; - } - } -# endif + mch_settmode(TMODE_COOK); /* handle CR and NL correctly */ #endif while ((maxlen < 0 || (int)(s - str) < maxlen) && *s != NUL) { if (!(silent_mode && p_verbose == 0)) { - /* NL --> CR NL translation (for Unix, not for "--version") */ - p = &buf[0]; - if (*s == '\n' && !info_message) - *p++ = '\r'; -#if defined(USE_CR) - else + // NL --> CR NL translation (for Unix, not for "--version") + if (*s == NL) + { + int n = (int)(s - p); + + buf = alloc(n + 3); + memcpy(buf, p, n); + if (!info_message) + buf[n++] = CAR; +#ifdef USE_CR + else #endif - *p++ = *s; - *p = '\0'; - if (info_message) /* informative message, not an error */ - mch_msg((char *)buf); - else - mch_errmsg((char *)buf); + buf[n++] = NL; + buf[n++] = NUL; + if (info_message) // informative message, not an error + mch_msg((char *)buf); + else + mch_errmsg((char *)buf); + vim_free(buf); + p = s + 1; + } } - /* primitive way to compute the current column */ + // primitive way to compute the current column #ifdef FEAT_RIGHTLEFT if (cmdmsg_rl) { - if (*s == '\r' || *s == '\n') + if (*s == CAR || *s == NL) msg_col = Columns - 1; else --msg_col; @@ -2628,19 +2616,27 @@ msg_puts_printf(char_u *str, int maxlen) else #endif { - if (*s == '\r' || *s == '\n') + if (*s == CAR || *s == NL) msg_col = 0; else ++msg_col; } ++s; } - msg_didout = TRUE; /* assume that line is not empty */ + + if (*p != NUL && !(silent_mode && p_verbose == 0)) + { + if (maxlen > 0 && STRLEN(p) > (size_t)maxlen) + p[maxlen] = 0; + if (info_message) + mch_msg((char *)p); + else + mch_errmsg((char *)p); + } + + msg_didout = TRUE; // assume that line is not empty #ifdef WIN3264 -# if !defined(FEAT_GUI_MSWIN) - vim_free(ccp); -# endif if (!(silent_mode && p_verbose == 0)) mch_settmode(TMODE_RAW); #endif @@ -2941,32 +2937,51 @@ do_more_prompt(int typed_char) void mch_errmsg(char *str) { +#if defined(WIN3264) && !defined(FEAT_GUI_MSWIN) + int len = STRLEN(str); + DWORD nwrite = 0; + DWORD mode = 0; + HANDLE h = GetStdHandle(STD_ERROR_HANDLE); + + if (GetConsoleMode(h, &mode) && enc_codepage >= 0 + && (int)GetConsoleCP() != enc_codepage) + { + WCHAR *w = enc_to_utf16((char_u *)str, &len); + + WriteConsoleW(h, w, len, &nwrite, NULL); + vim_free(w); + } + else + { + fprintf(stderr, "%s", str); + } +#else int len; -#if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI) +# if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI) /* On Unix use stderr if it's a tty. * When not going to start the GUI also use stderr. * On Mac, when started from Finder, stderr is the console. */ if ( -# ifdef UNIX -# ifdef MACOS_X +# ifdef UNIX +# ifdef MACOS_X (isatty(2) && strcmp("/dev/console", ttyname(2)) != 0) -# else +# else isatty(2) +# endif +# ifdef FEAT_GUI + || +# endif # endif # ifdef FEAT_GUI - || + !(gui.in_use || gui.starting) # endif -# endif -# ifdef FEAT_GUI - !(gui.in_use || gui.starting) -# endif ) { fprintf(stderr, "%s", str); return; } -#endif +# endif /* avoid a delay for a message that isn't there */ emsg_on_display = FALSE; @@ -2981,7 +2996,7 @@ mch_errmsg(char *str) { mch_memmove((char_u *)error_ga.ga_data + error_ga.ga_len, (char_u *)str, len); -#ifdef UNIX +# ifdef UNIX /* remove CR characters, they are displayed */ { char_u *p; @@ -2995,10 +3010,11 @@ mch_errmsg(char *str) *p = ' '; } } -#endif +# endif --len; /* don't count the NUL at the end */ error_ga.ga_len += len; } +#endif } /* @@ -3009,7 +3025,27 @@ mch_errmsg(char *str) void mch_msg(char *str) { -#if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI) +#if defined(WIN3264) && !defined(FEAT_GUI_MSWIN) + int len = STRLEN(str); + DWORD nwrite = 0; + DWORD mode; + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + + + if (GetConsoleMode(h, &mode) && enc_codepage >= 0 + && (int)GetConsoleCP() != enc_codepage) + { + WCHAR *w = enc_to_utf16((char_u *)str, &len); + + WriteConsoleW(h, w, len, &nwrite, NULL); + vim_free(w); + } + else + { + printf("%s", str); + } +#else +# if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI) /* On Unix use stdout if we have a tty. This allows "vim -h | more" and * uses mch_errmsg() when started from the desktop. * When not going to start the GUI also use stdout. @@ -3035,6 +3071,7 @@ mch_msg(char *str) } # endif mch_errmsg(str); +#endif } #endif /* USE_MCH_ERRMSG */ diff --git a/src/os_mswin.c b/src/os_mswin.c --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -675,6 +675,7 @@ mch_suspend(void) # undef display_errors #endif +#ifdef FEAT_GUI /* * Display the saved error message(s). */ @@ -690,13 +691,9 @@ display_errors(void) if (!isspace(*p)) { (void)gui_mch_dialog( -#ifdef FEAT_GUI gui.starting ? VIM_INFO : -#endif VIM_ERROR, -#ifdef FEAT_GUI gui.starting ? (char_u *)_("Message") : -#endif (char_u *)_("Error"), (char_u *)p, (char_u *)_("&Ok"), 1, NULL, FALSE); @@ -705,6 +702,13 @@ display_errors(void) ga_clear(&error_ga); } } +#else + void +display_errors(void) +{ + FlushFileBuffers(GetStdHandle(STD_ERROR_HANDLE)); +} +#endif #endif diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -784,6 +784,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 918, +/**/ 917, /**/ 916, diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -2093,7 +2093,7 @@ typedef enum { * functions of these names. The declarations would break if the defines had * been seen at that stage. But it must be before globals.h, where error_ga * is declared. */ -#if !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_X11) \ +#if !defined(MSWIN) && !defined(FEAT_GUI_X11) \ && !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_MAC) && !defined(PROTO) # define mch_errmsg(str) fprintf(stderr, "%s", (str)) # define display_errors() fflush(stderr)