From 4b76a9f729682ac74b5f4fd58cd9417b0055f664 Mon Sep 17 00:00:00 2001 From: Yee Cheng Chin Date: Fri, 10 Apr 2020 02:12:52 -0700 Subject: [PATCH] Fix MacVim's locale not having encoding when launched from Dock When launching MacVim not from terminal, macOS doesn't set the $LANG environment variable, and the locale API doesn't have a way to return the encoding (probably because everything is UTF-8). As such Vim would set the locale to something like "en_US", which breaks certain tools that expects an encoding part set. Fix this by simply appending ".UTF-8" to the constructed locale (e.g. "en_US.UTF-8") if $LANG doesn't exist. This makes sense as we default to UTF-8 in MacVim and macOS is basically UTF-8 native anyway. Also, add a test that will make sure this is the case. Fix #1033 --- src/os_mac_conv.c | 10 +++++++++ src/testdir/test_macvim.vim | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/os_mac_conv.c b/src/os_mac_conv.c index 6c52e7d20f..9de1dd837e 100644 --- a/src/os_mac_conv.c +++ b/src/os_mac_conv.c @@ -576,6 +576,16 @@ mac_lang_init(void) kLocaleRegionMask | kLocaleRegionVariantMask, sizeof buf, buf) == noErr && *buf) { +# ifdef FEAT_GUI_MACVIM + // This usually happens when the user directly launches from the Dock + // instead of terminal. macOS doesn't really provide the encoding part + // in the locale API, since it assumes everything is UTF-8 anyway. We + // should manually append a UTF-8 encoding component to the locale + // string. This helps tools that wants to parse the encoding compoennt + // of the locale. + strlcat(buf, ".UTF-8", sizeof(buf)/sizeof(char)); +# endif + vim_setenv((char_u *)"LANG", (char_u *)buf); # ifdef HAVE_LOCALE_H setlocale(LC_ALL, ""); diff --git a/src/testdir/test_macvim.vim b/src/testdir/test_macvim.vim index d1a62347ba..7de9a83bbc 100644 --- a/src/testdir/test_macvim.vim +++ b/src/testdir/test_macvim.vim @@ -1,6 +1,7 @@ " Test for MacVim behaviors and regressions source check.vim +source term_util.vim CheckFeature gui_macvim " Tests for basic existence of commands and options to make sure no @@ -54,3 +55,43 @@ func Test_macvim_mappings() call feedkeys("\", "xt") call assert_equal(5, g:marker_value) endfunc + +" Test that we correctly set the locale to have .UTF-8 if launching from the +" Dock or the $LANG env variable is not set. +func Test_macvim_default_locale_utf8() + CheckRunVimInTerminal + if !has('terminal') || !executable('/bin/sh') + return + endif + let buf = term_start('/bin/sh') + + " Wait for shell prompt. + call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))}) + + " Unset the $LANG environmental variable. This causes Vim to try to set a + " default one in macOS. + call term_sendkeys(buf, "unset LANG\") + + " Run Vim and ask it to output the $LANG variable. It should be + " automatically created since it doesn't exist. + call term_sendkeys(buf, v:progpath + \ . " --clean -X" + \ . " -c 'echo $LANG'\") + + " Wait for Vim to come up and show something in the status line. + let term_rows = term_getsize(buf)[0] + call term_wait(buf) + call WaitFor({-> len(term_getline(buf, term_rows)) > 0}) + + " Check that the locale actually has .UTF-8 in it. We can't check for + " "en_US.UTF-8" because we shouldn't assume what locale the tester is + " using. + call assert_match('^[a-zA-Z-_]\+\.UTF-8\>', term_getline(buf, term_rows), "Default locale doesn't have UTF-8 encoding set") + + " Cleanly exist from Vim/terminal and clean up. + call term_sendkeys(buf, ":qall!\") + call term_wait(buf) + call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))}) + call StopShellInTerminal(buf) + exe buf . 'bwipe!' +endfunc