patch 9.1.0559: translation of vim scripts can be improved

Problem:  translation of vim scripts can be improved
          (after v9.1.0509)
Solution: improve documentation, add tests, include missing
          libraries for the Windows CI
          (RestorerZ)

closes: #15100

Signed-off-by: RestorerZ <restorer@mail2k.ru>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
RestorerZ
2024-07-11 21:14:15 +02:00
committed by Christian Brabandt
parent 50dc83cf92
commit 965091001f
24 changed files with 608 additions and 90 deletions

View File

@ -434,6 +434,9 @@ jobs:
# SODIUM_MINGW_URL: https://download.libsodium.org/libsodium/releases/libsodium-%SODIUM_VER%-stable-mingw.tar.gz
SODIUM_MINGW_URL: https://github.com/jedisct1/libsodium/releases/download/%SODIUM_VER%-RELEASE/libsodium-%SODIUM_VER%-mingw.tar.gz
SODIUM_MINGW_VER: 26
# Gettext-tools, iconv and libraries
GETTEXT32_URL: https://github.com/mlocati/gettext-iconv-windows/releases/download/v0.21-v1.16/gettext0.21-iconv1.16-shared-32.zip
GETTEXT64_URL: https://github.com/mlocati/gettext-iconv-windows/releases/download/v0.21-v1.16/gettext0.21-iconv1.16-shared-64.zip
# Escape sequences
COL_RED: "\x1b[31m"
COL_GREEN: "\x1b[32m"
@ -501,6 +504,7 @@ jobs:
echo "SODIUM_DIR_SLASH=${SODIUM_DIR_SLASH}" >> $GITHUB_ENV
fi
echo "SODIUM_DIR=${SODIUM_DIR}" >> $GITHUB_ENV
echo "GETTEXT_PATH=D:\gettext${{ matrix.arch == 'x64' && '64' || '32' }}" >> $GITHUB_ENV
- uses: msys2/setup-msys2@v2
if: matrix.toolchain == 'mingw'
@ -522,6 +526,8 @@ jobs:
echo %LUA_RELEASE%>> urls.txt
echo %WINPTY_URL%>> urls.txt
echo %SODIUM_VER%>> urls.txt
echo %GETTEXT32_URL%>> urls.txt
echo %GETTEXT64_URL%>> urls.txt
- name: Cache downloaded files
uses: actions/cache@v4
@ -555,6 +561,12 @@ jobs:
mklink %SODIUM_LIB%\libsodium.dll %SODIUM_LIB%\libsodium-%SODIUM_MINGW_VER%.dll
)
echo %COL_GREEN%Download Gettext%COL_RESET%
call :downloadfile %GETTEXT${{ env.BITS }}_URL% downloads\gettext${{ env.BITS }}.zip
7z e -y downloads\gettext${{ env.BITS }}.zip -oD:\gettext${{ env.BITS }} > nul || exit 1
copy /y D:\gettext${{ env.BITS }}\libintl-8.dll src\ || exit 1
copy /y D:\gettext${{ env.BITS }}\libiconv-2.dll src\ || exit 1
goto :eof
:downloadfile

View File

@ -1,15 +1,20 @@
@echo off
:: Batch file for building/testing Vim on AppVeyor
set target=%1
set "GETTEXT_PATH=c:\gettext64\bin"
setlocal ENABLEDELAYEDEXPANSION
cd %APPVEYOR_BUILD_FOLDER%
:: Python3
set PYTHON3_VER=311
set PYTHON3_RELEASE=3.11.1
set PYTHON3_URL=https://www.python.org/ftp/python/%PYTHON3_RELEASE%/python-%PYTHON3_RELEASE%-amd64.exe
set PYTHON3_DIR=C:\python%PYTHON3_VER%-x64
set "PYTHON3_VER=311"
set "PYTHON3_RELEASE=3.11.1"
set "PYTHON3_URL=https://www.python.org/ftp/python/%PYTHON3_RELEASE%/python-%PYTHON3_RELEASE%-amd64.exe"
set "PYTHON3_DIR=C:\python%PYTHON3_VER%-x64"
:: Gettext-tools, iconv and libraries
set "GETTEXT64_URL=https://github.com/mlocati/gettext-iconv-windows/releases/download/v0.21-v1.16/gettext0.21-iconv1.16-shared-64.zip"
set "GETTEXT64_DIR=c:\gettext64"
set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
@ -43,6 +48,18 @@ if not exist %PYTHON3_DIR% (
AssociateFiles=0 Shortcuts=0 Include_doc=0 Include_launcher=0 ^
InstallLauncherAllUsers=0
)
:: GETTEXT
if not exist %GETTEXT64_DIR% (
mkdir %GETTEXT64_DIR%
call :downloadfile %GETTEXT64_URL% downloads\gettext64.zip
cmd /c powershell.exe -NoLogo -NoProfile -Command ^
Add-Type -AssemblyName 'System.IO.Compression.FileSystem'; ^
[System.IO.Compression.ZipFile]::ExtractToDirectory^('downloads\gettext64.zip', ^
'%GETTEXT64_DIR%'^)
copy /y %GETTEXT64_DIR%\bin\libintl-8.dll C:\projects\vim\src\ || exit 1
copy /y %GETTEXT64_DIR%\bin\libiconv-2.dll C:\projects\vim\src\ || exit 1
)
@echo off
goto :eof
@ -92,7 +109,7 @@ goto :eof
@echo on
cd src/testdir
:: Testing with MSVC gvim
path %PYTHON3_DIR%;%PATH%
path %PYTHON3_DIR%;%GETTEXT_PATH%;%PATH%
nmake -f Make_mvc.mak VIMPROG=..\gvim
nmake -f Make_mvc.mak clean
:: Testing with MSVC console version

View File

@ -1,4 +1,4 @@
*builtin.txt* For Vim version 9.1. Last change: 2024 Jul 09
*builtin.txt* For Vim version 9.1. Last change: 2024 Jul 11
VIM REFERENCE MANUAL by Bram Moolenaar
@ -1226,7 +1226,7 @@ bindtextdomain({package}, {path}) *bindtextdomain()*
Bind a specific {package} to a {path} so that the
|gettext()| function can be used to get language-specific
translations for a package. {path} is the directory name
for the translations. See |package-create|.
for the translations. See |package-translation|.
Return type: none
@ -5005,17 +5005,18 @@ gettagstack([{winnr}]) *gettagstack()*
gettext({text} [, {package}]) *gettext()*
Translate String {text} if possible.
This is mainly for use in the distributed Vim scripts. When
generating message translations the {text} is extracted by
xgettext, the translator can add the translated message in the
.po file and Vim will lookup the translation when gettext() is
called.
This is intended for use in Vim scripts. When generating
message translations the {text} is extracted by `xgettext`,
the translator can add translated messages into the .po file
and Vim will lookup the translation when gettext() is called.
For {text} double quoted strings are preferred, because
xgettext does not understand escaping in single quoted
strings.
`xgettext` does not support single quoted escaped text.
When the {package} is specified, the translation is looked up
for that specific package. You need to specify the path to
look for translations with the |bindtextdomain()| function.
for that specific package. This is mainly required for
third-party Vim scripts. You need to specify a path to the
translations with the |bindtextdomain()| function before
using the gettext() function.
Return type: |String|

View File

@ -1,4 +1,4 @@
*mlang.txt* For Vim version 9.1. Last change: 2022 Sep 17
*mlang.txt* For Vim version 9.1. Last change: 2024 Jul 11
VIM REFERENCE MANUAL by Bram Moolenaar
@ -59,7 +59,9 @@ use of "-" and "_".
:lan[guage] tim[e] {name}
:lan[guage] col[late] {name}
Set the current language (aka locale) to {name}.
The locale {name} must be a valid locale on your
The POSIX format of {name} is: >
language[_territory][.encoding]
< The locale {name} must be a valid locale on your
system. Some systems accept aliases like "en" or
"en_US", but some only accept the full specification
like "en_US.ISO_8859-1". On Unix systems you can use

View File

@ -1,4 +1,4 @@
*options.txt* For Vim version 9.1. Last change: 2024 Jul 09
*options.txt* For Vim version 9.1. Last change: 2024 Jul 11
VIM REFERENCE MANUAL by Bram Moolenaar
@ -6753,7 +6753,7 @@ A jump table for the options with a short description can be found at |Q_op|.
import/ files that are found by `:import`
indent/ indent scripts |indent-expression|
keymap/ key mapping files |mbyte-keymap|
lang/ menu translations |:menutrans|
lang/ message translations |:menutrans| and |multi-lang|
menu.vim GUI menus |menu.vim|
pack/ packages |:packadd|
plugin/ plugin scripts |write-plugin|

View File

@ -1,4 +1,4 @@
*repeat.txt* For Vim version 9.1. Last change: 2024 Jun 20
*repeat.txt* For Vim version 9.1. Last change: 2024 Jul 11
VIM REFERENCE MANUAL by Bram Moolenaar
@ -735,7 +735,7 @@ Your directory layout would be like this:
start/foobar/autoload/foo.vim " loaded when foo command used
start/foobar/doc/foo.txt " help for foo.vim
start/foobar/doc/tags " help tags
start/foobar/lang/<lang_id>/LC_MESSAGES/foo.po
start/foobar/lang/<lang_id>/LC_MESSAGES/foobar.mo
" messages for the plugin in the
" <lang_id> language. These files are
" optional.
@ -748,53 +748,345 @@ This allows for the user to do: >
mkdir ~/.vim/pack
cd ~/.vim/pack
git clone https://github.com/you/foobar.git myfoobar
<
Here "myfoobar" is a name that the user can choose, the only condition is that
it differs from other packages.
In your documentation you explain what the plugins do, and tell the user how
to load the optional plugin: >
:packadd! fooextra
<
You could add this packadd command in one of your plugins, to be executed when
the optional plugin is needed.
*package-doc* *package-documentation*
Run the `:helptags` command to generate the doc/tags file. Including this
generated file in the package means that the user can drop the package in the
pack directory and the help command works right away. Don't forget to re-run
the command after changing the plugin help: >
:helptags path/start/foobar/doc
:helptags path/opt/fooextra/doc
The messages that are in the lang/<lang_id>/LC_MESSAGES/foo.po file need to be
translated to a format that the |gettext()| function understands by running the
msgfmt program. This will result in a lang/<lang_id>/LC_MESSAGES/foo.mo
file. See |multilang| on how to specify languages.
In your plugin, you need to call the |bindtextdomain()| function as follows.
This assumes that the directory structure is as above: >
:call bindtextdomain("foo", fnamemodify(expand("<script>"), ':p:h')
.. '/../lang/')
<
You only need to do this once. After this call, you can use: >
:echo gettext("Hello", "foo")
*package-translation*
In order for a plugin to display translated messages, a few steps are
required.
The author of the plugin who likes to translate messages must define the name
of the package and the location of the directory where the translations can be
found using the |bindtextdomain()| function: >
:call bindtextdomain("foobar",
\ fnamemodify(expand("<script>"), ':p:h') .. '/../lang/')
<
to get the text "Hello" translated to the user's preferred language (if the
plugin messages have been translated to this language).
Where:
"foobar" is the unique package identifier by which the |gettext()|
function will later search for translation strings for this
plugin.
"lang/" is the relative or absolute path to the directory structure
where the translation file is located.
To create the foo.po file, you need to create a foo.pot file first. The
entries in this file need to be translated to the language(s) you want to be
supported by your plugin.
To create the foo.pot file, run the following command: >
cd ~/.vim/pack/start/foobar
make -f ~/src/vim/src/po/Makefile PACKAGE=foo \
PO_BASEDIR=~/src/vim/src/po PO_INPUTLIST= \
PO_VIM_JSLIST="plugin__foo.js plugin__bar.js \
autoload__foo.js" \
PO_VIM_INPUTLIST="plugin/foo.vim plugin/bar.vim autoload/foo.vim" \
foo.pot
The directory structure where the message translation files should be placed
is (from the top-level directory of the package):
"lang/<lang_id>/LC_MESSAGES". For the format of <lang_id> see |multi-lang|.
This function needs to be called only once during the initialization of the
plugin.
Once this is done, the |gettext()| function can be used to retrieve translated
messages: >
:echo gettext("Hello", "foobar")
<
Where:
"Hello" the message "Hello" to be translated into the user's language |:lang|
"foobar" the package identifier, which was previously defined using the
|bindtextdomain()| function.
After that you need to create a template file for translation - POT-file.
To do this, execute the following commands (using the Vim repository): >
cd ~/forkvim/src/po
make -f Makefile "PLUGPACKAGE={package}" \
"PO_PLUG_INPUTLIST={path/to/scripts-that-need-translations.vim}" \
["POT_PLUGPACKAGE_PATH={path/where/to/write/{package}.pot}" \]
["VIMPROG={path/to/vim} \]
{package}.pot
<
Where:
PLUGPACKAGE A variable containing the name of the package that we
specified in the |bindtextdomain()| and
|gettext()| functions, for example, "foobar".
PO_PLUG_INPUTLIST A variable containing scripts that have strings
to translate, i.e. where we specified the |gettext()|
function. Scripts are specified with an absolute
or relative path. Example: start/foobar/plugin/bar.vim
use blanks to separate scripts.
POT_PLUGPACKAGE_PATH A variable containing the directory where the prepared
POT file will be saved. This is not a required variable,
if no directory is specified, then the POT file will
be placed in the "src/po" directory.
VIMPROG A variable containing a directory with a working Vim.
If the Vim editor is already built and installed, and
is contained in the $PATH environment variable,
then you can specify just the name of the vim
executable.
{package}.pot This is the Target. It is specified as the name of
the package, for example, "foobar" with the addition
of the .pot extension.
Once a POT file is created, its contents are copied into separate PO files for
each language for which the translation will be prepared.
When the translation is finished, it is necessary to convert the PO files into
binary MO-files format and place these MO-files into the "lang/" directory, the
structure of which we created earlier.
To do this, run the following commands:
>
cd ~/forkvim/src/po
make -f Makefile "PLUGPACKAGE={package}" \
"PO_PLUGPACKAGE={path/to/{lang}.po}" \
["MO_PLUGPACKAGE_PATH={path/to/lang/<lang_id>/LC_MESSAGES}" \]
{package}.mo
<
Where:
PLUGPACKAGE A variable containing the name of the package that we
specified in the |bindtextdomain()| and |gettext()|
functions, for example, "foobar".
PO_PLUGPACKAGE A variable containing a PO file. The file is specified
with an absolute or relative path. For example,
"~/myproject/translate/en.po"
MO_PLUGPACKAGE_PATH A variable containing the structure of the "lang/"
directory, where the file with translations will be
placed, for example, "foobar.mo". This is not
a required variable, if the directory is not specified,
the MO file will be saved in the "src/po" directory.
{package}.mo This is the Target. It is specified as the name of
the package, for example, "foobar" with the addition
of the .mo extension.
*package-translate_example*
Let's show it all on some concrete example and translate the
"ftplugin/aap.vim" file into Russian and German.
First, let's prepare the "aap.vim" file, specifying |bindtextdomain()| and
|gettext()| function calls in it.
>
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
finish
endif
" Don't load another plugin for this buffer
let b:did_ftplugin = 1
call bindtextdomain("aap", fnamemodify(expand("<script>"), ':p:h') .. '/../lang/')
" Reset 'formatoptions', 'comments', 'commentstring' and 'expandtab' to undo
" this plugin.
let b:undo_ftplugin = "setl fo< com< cms< et<"
" Set 'formatoptions' to break comment lines but not other lines,
" and insert the comment leader when hitting <CR> or using "o".
setlocal fo-=t fo+=croql
" Set 'comments' to format dashed lists in comments.
setlocal comments=s:#\ -,m:#\ \ ,e:#,n:#,fb:-
setlocal commentstring=#\ %s
" Expand tabs to spaces to avoid trouble.
setlocal expandtab
if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
let b:browsefilter = gettext("Aap Recipe Files (*.aap)\t*.aap\n", "aap")
if has("win32")
let b:browsefilter ..= gettext("All Files (*.*)\t*\n", "aap")
else
let b:browsefilter ..= gettext("All Files (*)\t*\n", "aap")
endif
let b:undo_ftplugin ..= " | unlet! b:browsefilter"
endif
<
Now let's create a POT file for it (example uses Windows paths):
>
cd /d f:\forkvim\src\po
(the following command must be entered in one line, here it is separated for example)
nmake.exe -f Make_mvc.mak "PLUGPACKAGE=aap"
"PO_PLUG_INPUTLIST=d:\Programs\vim\vim91\ftplugin\aap.vim"
"POT_PLUGPACKAGE_PATH=e:\project\translate\plugins"
"VIMPROG=d:\Programs\vim\vim91\vim.exe"
aap.pot
<
After the POT file of our package is created, go to the directory where we
saved it and perform the translation.
>
cd /d e:\project\translate\plugins
copy aap.pot ru.po
copy aap.pot de.po
<
We have prepared a PO file with a translation into Russian:
# Test plugins translate ~
# ~
msgid "" ~
msgstr "" ~
"Project-Id-Version: aap\n" ~
"Report-Msgid-Bugs-To: \n" ~
"POT-Creation-Date: 2024-06-23 14:58+0300\n" ~
"PO-Revision-Date: 2024-06-23 14:58+0300\n" ~
"Last-Translator: Restorer\n" ~
"Language-Team: RuVim\n" ~
"Language: ru\n" ~
"MIME-Version: 1.0\n" ~
"Content-Type: text/plain; charset=UTF-8\n" ~
"Content-Transfer-Encoding: 8bit\n" ~
#: ../../runtime/ftplugin/aap.vim:32 ~
msgid "Aap Recipe Files (*.aap)\t*.aap\n" ~
msgstr "Файлы инструкций Aap (*.aap)\t*.aap\n" ~
#: ../../runtime/ftplugin/aap.vim:34 ~
msgid "All Files (*.*)\t*\n" ~
msgstr "Все файлы (*.*)\t*\n" ~
#: ../../runtime/ftplugin/aap.vim:36 ~
msgid "All Files (*)\t*\n" ~
msgstr "Все файлы (*)\t*\n" ~
And the PO file in German:
# Test plugins translate~
#~
msgid ""~
msgstr ""~
"Project-Id-Version: aap\n"~
"Report-Msgid-Bugs-To: \n"~
"POT-Creation-Date: 2024-06-23 14:58+0300\n"~
"PO-Revision-Date: 2024-06-24 13:11+0300\n"~
"Last-Translator: Restorer\n"~
"Language-Team: German\n"~
"Language: de\n"~
"MIME-Version: 1.0\n"~
"Content-Type: text/plain; charset=UTF-8\n"~
"Content-Transfer-Encoding: 8bit\n"~
#: ../../runtime/ftplugin/aap.vim:32~
msgid "Aap Recipe Files (*.aap)\t*.aap\n"~
msgstr "Aap-Rezeptdateien (*.aap)\t*.aap\n"~
#: ../../runtime/ftplugin/aap.vim:34~
msgid "All Files (*.*)\t*\n"~
msgstr "Alle Dateien (*.*)\t*.*\n"~
#: ../../runtime/ftplugin/aap.vim:36~
msgid "All Files (*)\t*\n"~
msgstr "Alle Dateien (*)\t*\n"~
Now convert these files into MO files so that |gettext()| can display message
translations. Note that since this is not a specialized plugin package, we
will put the MO files in the "lang/" directory of the Vim editor.
Type the following commands:
>
cd /d f:\forkvim\src\po
(the following command must be entered in one line, here it is separated for example)
For Russian:
nmake.exe -f Make_mvc.mak "PLUGPACKAGE=aap"
"PO_PLUGPACKAGE=e:\project\translate\plugins\ru.po"
"MO_PLUGPACKAGE_PATH=d:\Programs\vim\vim91\lang\ru\LC_MESSAGES"
aap.mo
For German:
nmake.exe -f Make_mvc.mak "PLUGPACKAGE=aap"
"PO_PLUGPACKAGE=e:\project\translate\plugins\de.po"
"MO_PLUGPACKAGE_PATH=d:\Programs\vim\vim91\lang\de\LC_MESSAGES"
aap.mo
<
That's it, the translations are ready and you can see the plugin's messages
in your native language.
Let's also try to translate a plugin package. For example, when a package
contains several scripts containing strings that need to be translated.
For example, let's translate the "netrw" package into Japanese.
For this example, we will translate only a few lines from this package.
Let's prepare the scripts where we need to translate the message strings.
The file "autoload\netrw.vim":
>
" Load Once:
if &cp || exists("g:loaded_netrw")
finish
endif
call bindtextdomain("netrw", fnamemodify(expand("<script>"), ':p:h') .. '/../lang/')
" Check that vim has patches that netrw requires.
" Patches needed for v7.4: 1557, and 213.
" (netrw will benefit from vim's having patch#656, too)
let s:needspatches=[1557,213]
if exists("s:needspatches")
for ptch in s:needspatches
if v:version < 704 || (v:version == 704 && !has("patch".ptch))
if !exists("s:needpatch{ptch}")
unsilent echomsg gettext("***sorry*** this version of netrw requires vim v7.4 with patch#", "netrw") .. ptch
endif
let s:needpatch{ptch}= 1
finish
endif
endfor
endif
<
The file "autoload\netrwSettings.vim":
>
" Load Once:
if exists("g:loaded_netrwSettings") || &cp
finish
endif
call bindtextdomain("netrw", fnamemodify(expand("<script>"), ':p:h') .. '/../lang/')
let g:loaded_netrwSettings = "v18"
if v:version < 700
echohl WarningMsg
echo gettext("***warning*** this version of netrwSettings needs vim 7.0", "netrw")
echohl Normal
finish
endif
<
Now we will prepare a POT file for further translation of messages.
Execute the following commands:
>
cd ~/forkvim/src/po
make -f Makefile "VIMPROG=/usr/local/bin/vim" "PLUGPACKAGE=netrw" \
"POT_PLUGPACKAGE_PATH=~/project/translate/plugins" \
"PO_PLUG_INPUTLIST=../../runtime/autoload/netrw.vim
../../runtime/autoload/netrwSettings.vim" \
netrw.pot
<
Go to the directory with the POT file and make the translation:
>
cd ~/project/translate/plugins
cp ./netrw.pot ja.po
<
When we have the translation ready in the "ja.po" file:
# Test plugins translate ~
# ~
msgid "" ~
msgstr "" ~
"Project-Id-Version: netrw\n" ~
"Report-Msgid-Bugs-To: \n" ~
"POT-Creation-Date: 2024-06-23 17:14+0300\n" ~
"PO-Revision-Date: 2024-06-23 17:14+0300\n" ~
"Last-Translator: Restorer\n" ~
"Language-Team: Japanese\n" ~
"Language: ja\n" ~
"MIME-Version: 1.0\n" ~
"Content-Type: text/plain; charset=UTF-8\n" ~
"Content-Transfer-Encoding: 8bit\n" ~
#: ../../runtime/autoload/netrw.vim:51 ~
msgid "***sorry*** this version of netrw requires vim v7.4 with patch#" ~
msgstr "" ~
"***申し訳ありません***このバージョンのnetrwには、パッチ付きのvim v7.4が必要です#" ~
#: ../../runtime/autoload/netrwSettings.vim:28 ~
msgid "***warning*** this version of netrwSettings needs vim 7.0" ~
msgstr "***警告***このバージョンのnetrwSettingsにはvim7.0が必要です" ~
Convert ja.po to a MO file:
>
cd ~/forkvim/src/po
make -f Makefile "PLUGPACKAGE=netrw" \
"PO_PLUGPACKAGE=~/project/translate/plugins/ja.po" \
"MO_PLUGPACKAGE_PATH=/usr/local/share/vim/vim91/lang/ja/LC_MESSAGES" \
netrw.mo
<
Executing those steps will allow you to get translation of any third-party
plug-in packages.
Dependencies between plugins ~
*packload-two-steps*

View File

@ -9308,6 +9308,10 @@ out_timeout channel.txt /*out_timeout*
p change.txt /*p*
pack-add repeat.txt /*pack-add*
package-create repeat.txt /*package-create*
package-doc repeat.txt /*package-doc*
package-documentation repeat.txt /*package-documentation*
package-translate_example repeat.txt /*package-translate_example*
package-translation repeat.txt /*package-translation*
packages repeat.txt /*packages*
packload-two-steps repeat.txt /*packload-two-steps*
page-down intro.txt /*page-down*

View File

@ -189,8 +189,8 @@ PO_VIM_INPUTLIST = \
../../runtime/defaults.vim
PO_VIM_JSLIST = \
________runtime__optwin.js \
________runtime__defaults.js
optwin.js \
defaults.js
# Arguments for xgettext to pick up messages to translate from the source code.
XGETTEXT_KEYWORDS = --keyword=_ --keyword=N_ --keyword=NGETTEXT:1,2 --keyword=PLURAL_MSG:2,4

View File

@ -40,7 +40,9 @@ VIMRUNTIME = ..\..\runtime
PACKAGE = vim
# Correct the following line for the where executeable file vim is
# installed. Please do not put the path in quotes.
!IFNDEF VIMPROG
VIMPROG = ..\vim.exe
!ENDIF
# Correct the following line for the directory where gettext et al is
# installed. Please do not put the path in quotes.
@ -498,25 +500,26 @@ files: $(PO_INPUTLIST)
first_time: files
"$(VIMPROG)" -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).po \
$(PO_VIM_INPUTLIST)
@ copy /a .\files+.\vim_to_js .\allfiles
set OLD_PO_FILE_INPUT=yes
set OLD_PO_FILE_OUTPUT=yes
$(XGETTEXT) --default-domain=$(LANGUAGE) --add-comments $(XGETTEXT_KEYWORDS) \
--files-from=.\files $(PO_VIM_JSLIST)
--files-from=.\allfiles
"$(VIMPROG)" -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).po \
$(PO_VIM_INPUTLIST)
$(RM) *.js
$(RM) *.js .\vim_to_js
$(PACKAGE).pot: files
"$(VIMPROG)" -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot \
$(PO_VIM_INPUTLIST)
@ copy /a .\files+.\vim_to_js .\allfiles
set OLD_PO_FILE_INPUT=yes
set OLD_PO_FILE_OUTPUT=yes
$(XGETTEXT) --default-domain=$(PACKAGE) --add-comments $(XGETTEXT_KEYWORDS) \
--files-from=.\files $(PO_VIM_JSLIST)
$(MV) $(PACKAGE).po $(PACKAGE).pot
$(XGETTEXT) --default-domain=$(PACKAGE) --output=$(PACKAGE).pot \
--add-comments $(XGETTEXT_KEYWORDS) --files-from=.\allfiles
"$(VIMPROG)" -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot \
$(PO_VIM_INPUTLIST)
$(RM) *.js
$(RM) *.js .\vim_to_js
# Only original translations with default encoding should be updated.
# The files that are converted to a different encoding clearly state "DO NOT EDIT".
@ -546,11 +549,34 @@ cleanup-po: $(LANGUAGE).po
cleanup-po-all: $(POFILES)
!"$(VIMPROG)" -u NONE -e -X -S cleanup.vim -c wq $**
#######
# For translations of plug-ins
#######
# Preparing the POT file of the plug-in package
POT_PLUGPACKAGE_PATH = $(MAKEDIR)
$(PLUGPACKAGE).pot : $(PO_PLUG_INPUTLIST)
"$(VIMPROG)" -u NONE --not-a-term -S tojavascript.vim \
$(PLUGPACKAGE).pot $**
$(XGETTEXT) --from-code=UTF-8 --default-domain=$(PLUGPACKAGE) \
--package-name=$(PLUGPACKAGE) \
--output-dir="$(POT_PLUGPACKAGE_PATH)" \
--output=$(PLUGPACKAGE).pot --files-from=.\vim_to_js
"$(VIMPROG)" -u NONE --not-a-term -S fixfilenames.vim \
"$(POT_PLUGPACKAGE_PATH)\$(PLUGPACKAGE).pot" $**
$(RM) *.js .\vim_to_js
# Converting the PO file of the plug-in package to the binary format of the MO file
MO_PLUGPACKAGE_PATH = $(MAKEDIR)
$(PLUGPACKAGE).mo : $(PO_PLUGPACKAGE)
$(MSGFMT) -o $(MO_PLUGPACKAGE_PATH)\$@ $?
clean: checkclean
$(RM) *.mo
$(RM) *.pot
$(RM) *.orig
$(RM) files
$(RM) files allfiles
$(RM) sjiscorr.obj sjiscorr.exe
# $(RM) big5corr.obj big5corr.exe

View File

@ -1,18 +1,17 @@
# Makefile for the Vim message translations.
PO_BASEDIR = .
# Include stuff found by configure.
include $(PO_BASEDIR)/../auto/config.mk
include ../auto/config.mk
# Get LANGUAGES, MOFILES, MOCONVERTED and others.
include $(PO_BASEDIR)/Make_all.mak
include Make_all.mak
# Note: ja.sjis, *.cp1250 and zh_CN.cp936 are only for MS-Windows, they are
# not installed on Unix.
PACKAGE = vim
SHELL = /bin/sh
VIMPROG = $(PO_BASEDIR)/../vim
VIMPROG = ../vim
# MacOS sed is locale aware, set $LANG to avoid problems.
SED = LANG=C sed
@ -41,8 +40,8 @@ converted: $(MOCONVERTED)
$(MSGFMTCMD) -o $@ $<
.po.ck:
$(VIMPROG) -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" -S check.vim \
-c "if error == 0 | q | else | num 2 | cq | endif" $<
$(VIMPROG) -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" \
-S check.vim -c "if error == 0 | q | else | num 2 | cq | endif" $<
touch $@
check: $(CHECKFILES)
@ -242,6 +241,7 @@ prefixcheck:
clean: checkclean
rm -f core core.* *.old.po *.mo *.pot sjiscorr
rm -f LINGUAS vim.desktop gvim.desktop tmp_*desktop
rm -f ./allfiles
# rm -f big5corr
distclean: clean
@ -262,21 +262,25 @@ PO_INPUTLIST = \
$(PACKAGE).pot: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST)
# Convert the Vim scripts to (what looks like) Javascript.
$(VIMPROG) -u NONE --not-a-term -S $(PO_BASEDIR)/tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
$(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot \
$(PO_VIM_INPUTLIST)
@ echo ${PO_INPUTLIST} | tr ' ' '\n' > ./allfiles
@ cat ./vim_to_js >> ./allfiles
# Create vim.pot.
$(XGETTEXT) --default-domain=$(PACKAGE) --add-comments \
$(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST)
mv -f $(PACKAGE).po $(PACKAGE).pot
$(XGETTEXT) --default-domain=$(PACKAGE) --output=$(PACKAGE).pot \
--add-comments $(XGETTEXT_KEYWORDS) --files-from=./allfiles
# Fix Vim scripts names, so that "gf" works.
$(VIMPROG) -u NONE --not-a-term -S $(PO_BASEDIR)/fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
$(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot \
$(PO_VIM_INPUTLIST)
# Delete the temporary files.
rm *.js
rm -f *.js ./vim_to_js
vim.desktop: vim.desktop.in $(POFILES)
echo $(LANGUAGES) | tr " " "\n" |$(SED) -e '/\./d' | sort > LINGUAS
$(MSGFMT) --desktop -d . --template vim.desktop.in -o tmp_vim.desktop
rm -f LINGUAS
if command -v desktop-file-validate; then desktop-file-validate tmp_vim.desktop; fi
if command -v desktop-file-validate; \
then desktop-file-validate tmp_vim.desktop; fi
mv tmp_vim.desktop vim.desktop
# The dependency on vim.desktop is only to avoid the two targets are build at
@ -285,7 +289,8 @@ gvim.desktop: gvim.desktop.in $(POFILES) vim.desktop
echo $(LANGUAGES) | tr " " "\n" |$(SED) -e '/\./d' | sort > LINGUAS
$(MSGFMT) --desktop -d . --template gvim.desktop.in -o tmp_gvim.desktop
rm -f LINGUAS
if command -v desktop-file-validate; then desktop-file-validate tmp_gvim.desktop; fi
if command -v desktop-file-validate; \
then desktop-file-validate tmp_gvim.desktop; fi
mv tmp_gvim.desktop gvim.desktop
# Only original translations with default encoding should be updated.
@ -302,3 +307,28 @@ $(LANGUAGES):
else \
echo "msgmerge for $@.po failed!"; mv $@.po.old $@.po; \
fi
#######
# For translations of plug-ins
#######
# Preparing the POT file of the plug-in package
POT_PLUGPACKAGE_PATH != pwd
$(PLUGPACKAGE).pot: $(PO_PLUG_INPUTLIST)
$(VIMPROG) -u NONE --not-a-term -S tojavascript.vim \
$(PLUGPACKAGE).pot $?
$(XGETTEXT) --from-code=UTF-8 --default-domain=$(PLUGPACKAGE) \
--package-name=$(PLUGPACKAGE) \
--output-dir=$(POT_PLUGPACKAGE_PATH) \
--output=$(PLUGPACKAGE).pot --files-from=./vim_to_js
$(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim \
$(POT_PLUGPACKAGE_PATH)/$(PLUGPACKAGE).pot $?
rm -f *.js ./vim_to_js
# Converting the PO file of the plug-in package to the binary format of the MO
MO_PLUGPACKAGE_PATH != pwd
$(PLUGPACKAGE).mo: $(PO_PLUGPACKAGE)
$(MSGFMTCMD) -o $(MO_PLUGPACKAGE_PATH)/$@ $<
# vim: set noet sw=8 ts=8 sts=0 wm=0 tw=0 ft=make:

View File

@ -160,3 +160,20 @@ convert ja.po to EUC-JP (supposed as your system encoding):
"Content-Type: text/plain; charset=EUC-JP\n"
There are examples in the Makefile for the conversions already supported.
TRANSLATION OF VIM THE EDITOR PLUG-INS
Vim supports displaying plugin messages for various native languages.
Translation is available both for plugins that are supplied as part of the Vim
editor (e.g. "optwin.vim") and for third-party plugin packages.
To translate the plugins supplied with the Vim editor, you must specify a
gettext() function call for the strings you want to translate.
The translation of these strings will be retrieved by gettext() from the MO
file "vim.mo".
For third-party plugins, it is necessary to specify a one-time call to the
bindtextdomain() function in scripts containing translation strings and for
all message strings to add a {package} argument to the gettext() function. For
more information, see ":help package-translation".

View File

@ -137,4 +137,22 @@ command:
nmake.exe -f Make_mvc.mak clean
TRANSLATION OF VIM THE EDITOR PLUG-INS
Vim supports displaying plugin messages for various native languages.
Translation is available both for plugins that are supplied as part of the Vim
editor (e.g. "optwin.vim") and for third-party plugin packages.
To translate the plugins supplied with the Vim editor, you must specify a
gettext() function call for the strings you want to translate.
The translation of these strings will be retrieved by gettext() from the MO
file "vim.mo".
For third-party plugins, it is necessary to specify a one-time call to the
bindtextdomain() function in scripts containing translation strings and for
all message strings to add a {package} argument to the gettext() function. For
more information, see ":help package-translation".
vim:tw=78:

View File

@ -3,9 +3,11 @@
set shortmess+=A
for name in argv()[1:]
let jsname = fnamemodify(name, ":r:gs?\\~?_?:gs?\\.?_?:gs?/?__?:gs?\\?__?") .. ".js"
exe "%s+" .. jsname .. "+" .. substitute(name, '\\', '/', 'g') .. "+"
let s:namenum = 0
for s:name in argv()[1:]
let s:jsname = fnamemodify(s:name, ":t:r") .. s:namenum .. ".js"
exe "%s+" .. s:jsname .. "+" .. substitute(s:name, '\\', '/', 'g') .. "+ge"
let s:namenum +=1
endfor
write

View File

@ -5,15 +5,20 @@
set shortmess+=A
for name in argv()[1:]
exe 'edit ' .. fnameescape(name)
let s:namenum = 0
let s:fls = []
for s:name in argv()[1:]
exe 'edit ' .. fnameescape(s:name)
" Strip comments, also after :set commands.
g/^\s*"/s/.*//
g/^\s*set .*"/s/.*//
" Write as .js file, xgettext recognizes them
exe 'w! ' .. fnamemodify(name, ":r:gs?\\~?_?:gs?\\.?_?:gs?/?__?:gs?\\?__?") .. ".js"
let s:fl = fnamemodify(s:name, ":t:r") .. s:namenum .. ".js"
exe 'w! ' .. s:fl
call add(s:fls, s:fl)
let s:namenum += 1
endfor
call writefile(s:fls, "vim_to_js")
quit

View File

@ -166,6 +166,7 @@ NEW_TESTS = \
test_gettext \
test_gettext_cp1251 \
test_gettext_utf8 \
test_gettext_make \
test_getvar \
test_gf \
test_glob2regpat \
@ -428,6 +429,7 @@ NEW_TESTS_RES = \
test_gettext.res \
test_gettext_cp1251.res \
test_gettext_utf8.res \
test_gettext_make.res \
test_getvar.res \
test_gf.res \
test_gn.res \

View File

@ -42,7 +42,7 @@ report:
else ( echo No failures reported > test_result.log )
$(VIMPROG) -u NONE $(COMMON_ARGS) -S summarize.vim messages
-if exist starttime del starttime
@echo.
@echo:
@echo Test results:
@cmd /c type test_result.log
@if exist test.log ( echo TEST FAILURE & exit /b 1 ) \
@ -56,7 +56,7 @@ $(NEW_TESTS):
-if exist test.log del test.log
-if exist messages del messages
-if exist starttime del starttime
@$(MAKE) -nologo -f Make_mvc.mak $@.res VIMPROG=$(VIMPROG)
@$(MAKE) -nologo -f Make_mvc.mak VIMPROG=$(VIMPROG) $@.res
@type messages
@if exist test.log exit 1

View File

@ -1,20 +1,20 @@
source check.vim
" TODO: Why does this fail on MacOS 14 and Windows MSVC (Github CI)?
" This fail on CI MacOS 14 because bindtextdomain() is not available there
" (missing library?)
CheckNotMac
CheckNotMSWindows
" Test for gettext()
func Test_gettext()
set encoding=cp1251
call bindtextdomain("__PACKAGE__", getcwd())
try
language ru_RU
language messages ru_RU
call assert_equal('<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ', gettext("ERROR: ", "__PACKAGE__"))
catch /^Vim\%((\a\+)\)\=:E197:/
throw "Skipped: not possible to set locale to ru (missing?)"
endtry
try
language en_GB.UTF-8
language messages en_GB.UTF-8
call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__"))
catch /^Vim\%((\a\+)\)\=:E197:/
throw "Skipped: not possible to set locale to en (missing?)"

View File

@ -0,0 +1,65 @@
source check.vim
"CheckNotMSWindows
CheckNotMac
" Test for package translation Makefile
func Test_gettext_makefile()
cd ../po
if has('win32')
call system('nmake.exe -f Make_mvc.mak "VIMPROG=' .. getenv('VIMPROG') ..
\ '" "GETTEXT_PATH=' .. getenv('GETTEXT_PATH') ..
\ '" PLUGPACKAGE=test_gettext
\ "PO_PLUG_INPUTLIST=..\testdir\test_gettext_makefile_in1.vim
\ ..\testdir\test_gettext_makefile_in2.vim
\ ..\testdir\test_gettext_makefile_in3.vim
\ ..\testdir\test_gettext_makefile_in4.vim" test_gettext.pot')
else
" Will it work on macOS?
call system("make -f Makefile PLUGPACKAGE=test_gettext
\ PO_PLUG_INPUTLIST=\"../testdir/test_gettext_makefile_in1.vim
\ ../testdir/test_gettext_makefile_in2.vim
\ ../testdir/test_gettext_makefile_in3.vim
\ ../testdir/test_gettext_makefile_in4.vim\" test_gettext.pot")
endif
let expected = [
\ '# SOME DESCRIPTIVE TITLE.',
\ '# Copyright (C) YEAR THE PACKAGE''S COPYRIGHT HOLDER',
\ '# This file is distributed under the same license as the test_gettext package.',
\ '# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.',
\ '#',
\ '#, fuzzy',
\ 'msgid ""',
\ 'msgstr ""',
\ '"Project-Id-Version: test_gettext\n"',
\ '"Report-Msgid-Bugs-To: \n"',
\ '"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"',
\ '"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"',
\ '"Language-Team: LANGUAGE <LL@li.org>\n"',
\ '"Language: \n"',
\ '"MIME-Version: 1.0\n"',
\ '"Content-Type: text/plain; charset=CHARSET\n"',
\ '"Content-Transfer-Encoding: 8bit\n"',
\ '',
\ '#: ../testdir/test_gettext_makefile_in1.vim:4 ../testdir/test_gettext_makefile_in1.vim:6',
\ '#: ../testdir/test_gettext_makefile_in2.vim:5 ../testdir/test_gettext_makefile_in4.vim:4',
\ 'msgid "This is a test"',
\ 'msgstr ""',
\ '',
\ '#: ../testdir/test_gettext_makefile_in1.vim:5',
\ 'msgid "This is another test"',
\ 'msgstr ""',
\ '',
\ '#: ../testdir/test_gettext_makefile_in2.vim:4',
\ 'msgid "This is a test from the second file"',
\ 'msgstr ""',
\ '',
\ '#: ../testdir/test_gettext_makefile_in4.vim:5',
\ 'msgid "This is a fourth test"',
\ 'msgstr ""']
let potfile = filter(readfile("test_gettext.pot"), 'v:val !~ "POT-Creation-Date"')
call assert_equal(expected, potfile)
call delete('test_gettext.pot')
cd -
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -0,0 +1,7 @@
" Test file for gettext() package makefile
" Last Change: 2024 Jun 01
echo gettext("This is a test", "test_gettext")
echo gettext("This is another test", "test_gettext")
echo gettext("This is a test", "test_gettext")
" vim: ts=8

View File

@ -0,0 +1,6 @@
" Test file for gettext() package makefile
" Last Change: 2024 Jun 01
echo gettext("This is a test from the second file", "test_gettext")
echo gettext("This is a test", "test_gettext")
" vim: ts=8

View File

@ -0,0 +1,4 @@
" Test file for gettext() package makefile
" Last Change: 2024 Jun 01
" vim: ts=8

View File

@ -0,0 +1,6 @@
" Test file for gettext() package makefile
" Last Change: 2024 Jun 01
echo gettext("This is a test", "test_gettext")
echo gettext("This is a fourth test", "test_gettext")
" vim: ts=8

View File

@ -1,20 +1,20 @@
source check.vim
" TODO: Why does this fail on MacOS 14 and Windows MSVC (Github CI)?
" This fail on CI MacOS 14 because bindtextdomain() is not available there
" (missing library?)
CheckNotMac
CheckNotMSWindows
" Test for gettext()
func Test_gettext()
set encoding=utf-8
call bindtextdomain("__PACKAGE__", getcwd())
try
language ru_RU
language messages ru_RU
call assert_equal('ОШИБКА: ', gettext("ERROR: ", "__PACKAGE__"))
catch /^Vim\%((\a\+)\)\=:E197:/
throw "Skipped: not possible to set locale to ru (missing?)"
endtry
try
language en_GB.UTF-8
language messages en_GB.UTF-8
call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__"))
catch /^Vim\%((\a\+)\)\=:E197:/
throw "Skipped: not possible to set locale to en (missing?)"

View File

@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
559,
/**/
558,
/**/