diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2019-08-12 02:42:13 +0200 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2019-08-12 02:42:13 +0200 |
commit | ad4eb18e43d56d7ec93770af674418451daae694 (patch) | |
tree | 4779887d56e4640f60b5c4d796def4ebb3e4af6e | |
parent | 48dc6344d665a7537fb000ec64ab95a37faa07f3 (diff) | |
parent | 2fbeea8326e2e3724482d4131f10c1b1990a1687 (diff) | |
download | rneovim-ad4eb18e43d56d7ec93770af674418451daae694.tar.gz rneovim-ad4eb18e43d56d7ec93770af674418451daae694.tar.bz2 rneovim-ad4eb18e43d56d7ec93770af674418451daae694.zip |
Merge #10098 'win: fix msg_puts_printf()'
-rw-r--r-- | config/config.h.in | 1 | ||||
-rw-r--r-- | src/nvim/eval.c | 4 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 3 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.c | 16 | ||||
-rw-r--r-- | src/nvim/globals.h | 5 | ||||
-rw-r--r-- | src/nvim/main.c | 24 | ||||
-rw-r--r-- | src/nvim/message.c | 99 | ||||
-rw-r--r-- | src/nvim/option.c | 6 | ||||
-rw-r--r-- | src/nvim/os/env.c | 20 | ||||
-rw-r--r-- | src/nvim/vim.h | 7 | ||||
-rw-r--r-- | test/functional/core/startup_spec.lua | 25 | ||||
-rw-r--r-- | test/functional/ui/messages_spec.lua | 50 |
12 files changed, 127 insertions, 133 deletions
diff --git a/config/config.h.in b/config/config.h.in index 3216ab7556..0cb87c6b4d 100644 --- a/config/config.h.in +++ b/config/config.h.in @@ -13,7 +13,6 @@ #endif #define PROJECT_NAME "@PROJECT_NAME@" -#define LOCALE_INSTALL_DIR "@CMAKE_INSTALL_FULL_LOCALEDIR@" #cmakedefine HAVE__NSGETENVIRON #cmakedefine HAVE_FD_CLOEXEC diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 1d221bb600..a3a66a5764 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1989,7 +1989,7 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, } } if (p != NULL) { - vim_setenv(name, p); + os_setenv(name, p, 1); if (STRICMP(name, "HOME") == 0) { init_homedir(); } else if (didset_vim && STRICMP(name, "VIM") == 0) { @@ -15359,7 +15359,7 @@ static void f_setenv(typval_T *argvars, typval_T *rettv, FunPtr fptr) && argvars[1].vval.v_number == kSpecialVarNull) { os_unsetenv(name); } else { - vim_setenv(name, tv_get_string_buf(&argvars[1], valbuf)); + os_setenv(name, tv_get_string_buf(&argvars[1], valbuf), 1); } } diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index e256351de2..a0fbde008b 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -1392,9 +1392,6 @@ do_shell( msg_row = Rows - 1; msg_col = 0; - // display any error messages now - display_errors(); - apply_autocmds(EVENT_SHELLCMDPOST, NULL, NULL, FALSE, curbuf); } diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 7c28461f4c..408c6dce79 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2819,10 +2819,10 @@ void ex_packadd(exarg_T *eap) /// ":options" void ex_options(exarg_T *eap) { - vim_setenv("OPTWIN_CMD", cmdmod.tab ? "tab" : ""); - vim_setenv("OPTWIN_CMD", - cmdmod.tab ? "tab" : - (cmdmod.split & WSP_VERT) ? "vert" : ""); + os_setenv("OPTWIN_CMD", cmdmod.tab ? "tab" : "", 1); + os_setenv("OPTWIN_CMD", + cmdmod.tab ? "tab" : + (cmdmod.split & WSP_VERT) ? "vert" : "", 1); cmd_source((char_u *)SYS_OPTWIN_FILE, NULL); } @@ -3927,19 +3927,19 @@ void ex_language(exarg_T *eap) _nl_msg_cat_cntr++; #endif // Reset $LC_ALL, otherwise it would overrule everything. - vim_setenv("LC_ALL", ""); + os_setenv("LC_ALL", "", 1); if (what != LC_TIME) { // Tell gettext() what to translate to. It apparently doesn't // use the currently effective locale. if (what == LC_ALL) { - vim_setenv("LANG", (char *)name); + os_setenv("LANG", (char *)name, 1); // Clear $LANGUAGE because GNU gettext uses it. - vim_setenv("LANGUAGE", ""); + os_setenv("LANGUAGE", "", 1); } if (what != LC_CTYPE) { - vim_setenv("LC_MESSAGES", (char *)name); + os_setenv("LC_MESSAGES", (char *)name, 1); set_helplang_default((char *)name); } } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index b095e759d9..3bdbff79b4 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -895,11 +895,6 @@ EXTERN disptick_T display_tick INIT(= 0); * cursor position in Insert mode. */ EXTERN linenr_T spell_redraw_lnum INIT(= 0); -#ifdef USE_MCH_ERRMSG -// Grow array to collect error messages in until they can be displayed. -EXTERN garray_T error_ga INIT(= GA_EMPTY_INIT_VALUE); -#endif - /* * The error messages that can be shared are included here. diff --git a/src/nvim/main.c b/src/nvim/main.c index 6bb3c37b92..5aa7ed42d3 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -707,22 +707,14 @@ static void init_locale(void) setlocale(LC_NUMERIC, "C"); # endif -# ifdef LOCALE_INSTALL_DIR // gnu/linux standard: $prefix/share/locale - bindtextdomain(PROJECT_NAME, LOCALE_INSTALL_DIR); -# else // old vim style: $runtime/lang - { - char_u *p; - - // expand_env() doesn't work yet, because g_chartab[] is not - // initialized yet, call vim_getenv() directly - p = (char_u *)vim_getenv("VIMRUNTIME"); - if (p != NULL && *p != NUL) { - vim_snprintf((char *)NameBuff, MAXPATHL, "%s/lang", p); - bindtextdomain(PROJECT_NAME, (char *)NameBuff); - } - xfree(p); - } -# endif + char localepath[MAXPATHL] = { 0 }; + snprintf(localepath, sizeof(localepath), "%s", get_vim_var_str(VV_PROGPATH)); + char *tail = (char *)path_tail_with_sep((char_u *)localepath); + *tail = NUL; + tail = (char *)path_tail((char_u *)localepath); + xstrlcpy(tail, "share/locale", + sizeof(localepath) - (size_t)(tail - localepath)); + bindtextdomain(PROJECT_NAME, localepath); textdomain(PROJECT_NAME); TIME_MSG("locale set"); } diff --git a/src/nvim/message.c b/src/nvim/message.c index 12da48347e..b043df17d3 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2305,18 +2305,19 @@ int msg_use_printf(void) static void msg_puts_printf(const char *str, const ptrdiff_t maxlen) { const char *s = str; - char buf[4]; + char buf[7]; char *p; while ((maxlen < 0 || s - str < maxlen) && *s != NUL) { + int len = utf_ptr2len((const char_u *)s); 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'; } - *p++ = *s; - *p = '\0'; + memcpy(p, s, len); + *(p + len) = '\0'; if (info_message) { mch_msg(buf); } else { @@ -2324,21 +2325,22 @@ static void msg_puts_printf(const char *str, const ptrdiff_t maxlen) } } + int cw = utf_char2cells(utf_ptr2char((const char_u *)s)); // primitive way to compute the current column if (cmdmsg_rl) { if (*s == '\r' || *s == '\n') { msg_col = Columns - 1; } else { - msg_col--; + msg_col -= cw; } } else { if (*s == '\r' || *s == '\n') { msg_col = 0; } else { - msg_col++; + msg_col += cw; } } - s++; + s += len; } msg_didout = true; // assume that line is not empty } @@ -2554,81 +2556,32 @@ static int do_more_prompt(int typed_char) return retval; } -#if defined(USE_MCH_ERRMSG) - -#ifdef mch_errmsg -# undef mch_errmsg -#endif -#ifdef mch_msg -# undef mch_msg -#endif - -/* - * Give an error message. To be used when the screen hasn't been initialized - * yet. When stderr can't be used, collect error messages until the GUI has - * started and they can be displayed in a message box. - */ -void mch_errmsg(const char *const str) - FUNC_ATTR_NONNULL_ALL +#if defined(WIN32) +void mch_errmsg(char *str) { -#ifdef UNIX - /* 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 (os_isatty(2)) { - fprintf(stderr, "%s", str); - return; - } -#endif - - /* avoid a delay for a message that isn't there */ - emsg_on_display = FALSE; - - const size_t len = strlen(str) + 1; - if (error_ga.ga_data == NULL) { - ga_set_growsize(&error_ga, 80); - error_ga.ga_itemsize = 1; - } - ga_grow(&error_ga, len); - memmove(error_ga.ga_data + error_ga.ga_len, str, len); -#ifdef UNIX - /* remove CR characters, they are displayed */ - { - char_u *p; - - p = (char_u *)error_ga.ga_data + error_ga.ga_len; - for (;; ) { - p = vim_strchr(p, '\r'); - if (p == NULL) - break; - *p = ' '; - } + wchar_t *utf16str; + int conversion_result = utf8_to_utf16((str), &utf16str); + if (conversion_result != 0) { + EMSG2("utf8_to_utf16 failed: %d", conversion_result); + } else { + fwprintf(stderr, L"%ls", utf16str); + xfree(utf16str); } -#endif - --len; /* don't count the NUL at the end */ - error_ga.ga_len += len; } -/* - * Give a message. To be used when the screen hasn't been initialized yet. - * When there is no tty, collect messages until the GUI has started and they - * can be displayed in a message box. - */ +// Give a message. To be used when the UI is not initialized yet. void mch_msg(char *str) { -#ifdef UNIX - /* 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. - * On Mac, when started from Finder, stderr is the console. */ - if (os_isatty(2)) { - printf("%s", str); - return; + wchar_t *utf16str; + int conversion_result = utf8_to_utf16((str), &utf16str); + if (conversion_result != 0) { + EMSG2("utf8_to_utf16 failed: %d", conversion_result); + } else { + wprintf(L"%ls", utf16str); + xfree(utf16str); } -# endif - mch_errmsg(str); } -#endif /* USE_MCH_ERRMSG */ +#endif // WIN32 /* * Put a character on the screen at the current message position and advance diff --git a/src/nvim/option.c b/src/nvim/option.c index 40c1358fa5..55b69edba0 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2609,11 +2609,11 @@ did_set_string_option( } else if (varp == &p_hf) { // 'helpfile' // May compute new values for $VIM and $VIMRUNTIME if (didset_vim) { - vim_setenv("VIM", ""); + os_setenv("VIM", "", 1); didset_vim = false; } if (didset_vimruntime) { - vim_setenv("VIMRUNTIME", ""); + os_setenv("VIMRUNTIME", "", 1); didset_vimruntime = false; } } else if (varp == &curwin->w_p_cc) { // 'colorcolumn' @@ -6778,7 +6778,7 @@ void vimrc_found(char_u *fname, char_u *envname) // Set $MYVIMRC to the first vimrc file found. p = FullName_save((char *)fname, false); if (p != NULL) { - vim_setenv((char *)envname, p); + os_setenv((char *)envname, p, 1); xfree(p); } } else { diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 33b67a8116..62457e155c 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -845,10 +845,10 @@ char *vim_getenv(const char *name) // next time, and others can also use it (e.g. Perl). if (vim_path != NULL) { if (vimruntime) { - vim_setenv("VIMRUNTIME", vim_path); + os_setenv("VIMRUNTIME", vim_path, 1); didset_vimruntime = true; } else { - vim_setenv("VIM", vim_path); + os_setenv("VIM", vim_path, 1); didset_vim = true; } } @@ -995,22 +995,6 @@ char_u * home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET return dst; } -/// Vim setenv() wrapper with special handling for $VIMRUNTIME to keep the -/// localization machinery sane. -void vim_setenv(const char *name, const char *val) -{ - os_setenv(name, val, 1); -#ifndef LOCALE_INSTALL_DIR - // When setting $VIMRUNTIME adjust the directory to find message - // translations to $VIMRUNTIME/lang. - if (*val != NUL && STRICMP(name, "VIMRUNTIME") == 0) { - char *buf = (char *)concat_str((char_u *)val, (char_u *)"/lang"); - bindtextdomain(PROJECT_NAME, buf); - xfree(buf); - } -#endif -} - /// Function given to ExpandGeneric() to obtain an environment variable name. char_u *get_env_name(expand_T *xp, int idx) diff --git a/src/nvim/vim.h b/src/nvim/vim.h index 3e0a5907be..60737014b3 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -287,9 +287,10 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext() // 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. -#define mch_errmsg(str) fprintf(stderr, "%s", (str)) -#define display_errors() fflush(stderr) -#define mch_msg(str) printf("%s", (str)) +#ifndef WIN32 +# define mch_errmsg(str) fprintf(stderr, "%s", (str)) +# define mch_msg(str) printf("%s", (str)) +#endif #include "nvim/globals.h" // global variables and messages #include "nvim/buffer_defs.h" // buffer and windows diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index 62a45fdf88..3b32c42ec0 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -226,6 +226,31 @@ describe('startup', function() clear{env={CDPATH='~doesnotexist'}} eq(',~doesnotexist', eval('&cdpath')) end) + + it('ENTER dismisses early message #7967', function() + local screen + screen = Screen.new(60, 6) + screen:attach() + command([[let g:id = termopen('"]]..nvim_prog.. + [[" -u NONE -i NONE --cmd "set noruler" --cmd "let g:foo = g:bar"')]]) + screen:expect([[ + ^ | + Error detected while processing pre-vimrc command line: | + E121: Undefined variable: g:bar | + E15: Invalid expression: g:bar | + Press ENTER or type command to continue | + | + ]]) + command([[call chansend(g:id, "\n")]]) + screen:expect([[ + ^ | + ~ | + ~ | + [No Name] | + | + | + ]]) + end) end) describe('sysinit', function() diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index 9a1a0f66a2..ed65c4526f 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -6,7 +6,10 @@ local eq = helpers.eq local command = helpers.command local set_method_error = helpers.set_method_error local meths = helpers.meths - +local test_build_dir = helpers.test_build_dir +local nvim_prog = helpers.nvim_prog +local iswin = helpers.iswin +local exc_exec = helpers.exc_exec describe('ui/ext_messages', function() local screen @@ -1004,3 +1007,48 @@ describe('ui/ext_messages', function() }} end) end) + +describe('ui/msg_puts_printf', function() + it('output multibyte characters correctly', function() + local screen + local cmd = '' + local locale_dir = test_build_dir..'/share/locale/ja/LC_MESSAGES' + + clear({env={LANG='ja_JP.UTF-8'}}) + screen = Screen.new(25, 5) + screen:attach() + + if iswin() then + if os.execute('chcp 932 > NUL 2>&1') ~= 0 then + pending('missing japanese language features', function() end) + return + else + cmd = 'chcp 932 > NULL & ' + end + else + if (exc_exec('lang ja_JP.UTF-8') ~= 0) then + pending('Locale ja_JP.UTF-8 not supported', function() end) + return + elseif helpers.isCI() then + -- Fails non--Windows CI. Message catalog direcotry issue? + pending('fails on unix CI', function() end) + return + end + end + + os.execute('cmake -E make_directory '..locale_dir) + os.execute('cmake -E copy '..test_build_dir..'/src/nvim/po/ja.mo '..locale_dir..'/nvim.mo') + + cmd = cmd..'"'..nvim_prog..'" -u NONE -i NONE -Es -V1' + command([[call termopen(']]..cmd..[[')]]) + screen:expect([[ + ^Exモードに入ります. ノー | + マルモードに戻るには"visu| + al"と入力してください. | + : | + | + ]]) + + os.execute('cmake -E remove_directory '..test_build_dir..'/share') + end) +end) |