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
This commit is contained in:
Yee Cheng Chin
2020-04-10 02:12:52 -07:00
parent dce1eacbbb
commit 4b76a9f729
2 changed files with 51 additions and 0 deletions
+10
View File
@@ -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, "");
+41
View File
@@ -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("\<ForceClick>", "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\<CR>")
" 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'\<CR>")
" 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!\<CR>")
call term_wait(buf)
call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))})
call StopShellInTerminal(buf)
exe buf . 'bwipe!'
endfunc