Skip to content

Commit 0b39c3f

Browse files
committed
patch 8.2.1544: cannot translate messages in a Vim script
Problem: Cannot translate messages in a Vim script. Solution: Add gettext(). Try it out for a few messages in the options window.
1 parent 25859dd commit 0b39c3f

File tree

10 files changed

+136
-15
lines changed

10 files changed

+136
-15
lines changed

Filelist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,8 @@ LANG_SRC = \
10281028
src/po/README_mvc.txt \
10291029
src/po/check.vim \
10301030
src/po/cleanup.vim \
1031+
src/po/tojavascript.vim \
1032+
src/po/fixfilenames.vim \
10311033
src/po/Makefile \
10321034
src/po/Make_all.mak \
10331035
src/po/Make_cyg.mak \

runtime/doc/eval.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2546,6 +2546,7 @@ gettabvar({nr}, {varname} [, {def}])
25462546
gettabwinvar({tabnr}, {winnr}, {name} [, {def}])
25472547
any {name} in {winnr} in tab page {tabnr}
25482548
gettagstack([{nr}]) Dict get the tag stack of window {nr}
2549+
gettext({text}) String lookup translation of {text}
25492550
getwininfo([{winid}]) List list of info about each window
25502551
getwinpos([{timeout}]) List X and Y coord in pixels of the Vim window
25512552
getwinposx() Number X coord in pixels of the Vim window
@@ -5827,6 +5828,19 @@ gettagstack([{nr}]) *gettagstack()*
58275828
Can also be used as a |method|: >
58285829
GetWinnr()->gettagstack()
58295830

5831+
5832+
gettext({text}) *gettext()*
5833+
Translate {text} if possible.
5834+
This is mainly for use in the distributed Vim scripts. When
5835+
generating message translations the {text} is extracted by
5836+
xgettext, the translator can add the translated message in the
5837+
.po file and Vim will lookup the translation when gettext() is
5838+
called.
5839+
For {text} double quoted strings are preferred, because
5840+
xgettext does not understand escaping in single quoted
5841+
strings.
5842+
5843+
58305844
getwininfo([{winid}]) *getwininfo()*
58315845
Returns information about windows as a |List| with Dictionaries.
58325846

runtime/doc/usr_41.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ String manipulation: *string-functions*
628628
execute() execute an Ex command and get the output
629629
win_execute() like execute() but in a specified window
630630
trim() trim characters from a string
631+
gettext() lookup message translation
631632

632633
List manipulation: *list-functions*
633634
get() get an item without error for wrong index

runtime/optwin.vim

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
" These commands create the option window.
22
"
33
" Maintainer: Bram Moolenaar <Bram@vim.org>
4-
" Last Change: 2020 Jun 10
4+
" Last Change: 2020 aug 30
55

66
" If there already is an option window, jump to that one.
77
let buf = bufnr('option-window')
@@ -145,13 +145,13 @@ exe $OPTWIN_CMD . ' new option-window'
145145
setlocal ts=15 tw=0 noro buftype=nofile
146146

147147
" Insert help and a "set" command for each option.
148-
call append(0, '" Each "set" line shows the current value of an option (on the left).')
149-
call append(1, '" Hit <CR> on a "set" line to execute it.')
150-
call append(2, '" A boolean option will be toggled.')
151-
call append(3, '" For other options you can edit the value before hitting <CR>.')
152-
call append(4, '" Hit <CR> on a help line to open a help window on this option.')
153-
call append(5, '" Hit <CR> on an index line to jump there.')
154-
call append(6, '" Hit <Space> on a "set" line to refresh it.')
148+
call append(0, gettext('" Each "set" line shows the current value of an option (on the left).'))
149+
call append(1, gettext('" Hit <Enter> on a "set" line to execute it.'))
150+
call append(2, gettext('" A boolean option will be toggled.'))
151+
call append(3, gettext('" For other options you can edit the value before hitting <Enter>.'))
152+
call append(4, gettext('" Hit <Enter> on a help line to open a help window on this option.'))
153+
call append(5, gettext('" Hit <Enter> on an index line to jump there.'))
154+
call append(6, gettext('" Hit <Space> on a "set" line to refresh it.'))
155155

156156
" These functions are called often below. Keep them fast!
157157

src/evalfunc.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ static void f_getreg(typval_T *argvars, typval_T *rettv);
9797
static void f_getreginfo(typval_T *argvars, typval_T *rettv);
9898
static void f_getregtype(typval_T *argvars, typval_T *rettv);
9999
static void f_gettagstack(typval_T *argvars, typval_T *rettv);
100+
static void f_gettext(typval_T *argvars, typval_T *rettv);
100101
static void f_haslocaldir(typval_T *argvars, typval_T *rettv);
101102
static void f_hasmapto(typval_T *argvars, typval_T *rettv);
102103
static void f_hlID(typval_T *argvars, typval_T *rettv);
@@ -667,6 +668,7 @@ static funcentry_T global_functions[] =
667668
{"gettabvar", 2, 3, FEARG_1, ret_any, f_gettabvar},
668669
{"gettabwinvar", 3, 4, FEARG_1, ret_any, f_gettabwinvar},
669670
{"gettagstack", 0, 1, FEARG_1, ret_dict_any, f_gettagstack},
671+
{"gettext", 1, 1, FEARG_1, ret_string, f_gettext},
670672
{"getwininfo", 0, 1, FEARG_1, ret_list_dict_any, f_getwininfo},
671673
{"getwinpos", 0, 1, FEARG_1, ret_list_number, f_getwinpos},
672674
{"getwinposx", 0, 0, 0, ret_number, f_getwinposx},
@@ -3437,6 +3439,26 @@ f_gettagstack(typval_T *argvars, typval_T *rettv)
34373439
get_tagstack(wp, rettv->vval.v_dict);
34383440
}
34393441

3442+
/*
3443+
* "gettext()" function
3444+
*/
3445+
static void
3446+
f_gettext(typval_T *argvars, typval_T *rettv)
3447+
{
3448+
if (argvars[0].v_type != VAR_STRING
3449+
|| argvars[0].vval.v_string == NULL
3450+
|| *argvars[0].vval.v_string == NUL)
3451+
{
3452+
semsg(_(e_invarg2), tv_get_string(&argvars[0]));
3453+
}
3454+
else
3455+
{
3456+
rettv->v_type = VAR_STRING;
3457+
rettv->vval.v_string = vim_strsave(
3458+
(char_u *)_(argvars[0].vval.v_string));
3459+
}
3460+
}
3461+
34403462
// for VIM_VERSION_ defines
34413463
#include "version.h"
34423464

src/po/Makefile

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ all: $(MOFILES) $(MOCONVERTED) $(MSGFMT_DESKTOP)
3636

3737
check: $(CHECKFILES)
3838

39+
# installing for real
3940
install: $(MOFILES) $(MOCONVERTED)
4041
@$(MAKE) prefixcheck
4142
for lang in $(LANGUAGES); do \
@@ -61,6 +62,24 @@ uninstall:
6162
rm -f $(LOCALEDIR)/$$lang/LC_MESSAGES/$(PACKAGE).mo; \
6263
done
6364

65+
# installing for local tryout into ../../runtime/lang
66+
tryoutinstall: $(MOFILES) $(MOCONVERTED)
67+
@$(MAKE) prefixcheck
68+
for lang in $(LANGUAGES); do \
69+
dir=../../runtime/lang/$$lang/; \
70+
if test ! -x "$$dir"; then \
71+
mkdir $$dir; chmod 755 $$dir; \
72+
fi; \
73+
dir=../../runtime/lang/$$lang/LC_MESSAGES; \
74+
if test ! -x "$$dir"; then \
75+
mkdir $$dir; chmod 755 $$dir; \
76+
fi; \
77+
if test -r $$lang.mo; then \
78+
cp $$lang.mo $$dir/$(PACKAGE).mo; \
79+
chmod 644 $$dir/$(PACKAGE).mo; \
80+
fi; \
81+
done
82+
6483
converted: $(MOCONVERTED)
6584

6685
# nl.po was added later, if it does not exist use a file with just a # in it
@@ -158,12 +177,34 @@ distclean: clean
158177
checkclean:
159178
rm -f *.ck
160179

161-
$(PACKAGE).pot: ../*.c ../if_perl.xs ../GvimExt/gvimext.cpp ../globals.h ../if_py_both.h ../vim.h gvim.desktop.in vim.desktop.in
162-
cd ..; $(XGETTEXT) --default-domain=$(PACKAGE) \
163-
--add-comments --keyword=_ --keyword=N_ --keyword=NGETTEXT:1,2 \
164-
*.c if_perl.xs GvimExt/gvimext.cpp globals.h if_py_both.h vim.h \
165-
po/gvim.desktop.in po/vim.desktop.in
166-
mv -f ../$(PACKAGE).po $(PACKAGE).pot
180+
PO_INPUTLIST = \
181+
../*.c \
182+
../if_perl.xs \
183+
../GvimExt/gvimext.cpp \
184+
../globals.h \
185+
../if_py_both.h \
186+
../vim.h \
187+
gvim.desktop.in \
188+
vim.desktop.in
189+
190+
PO_VIM_INPUTLIST = \
191+
../../runtime/optwin.vim
192+
193+
PO_VIM_JSLIST = \
194+
optwin.js
195+
196+
$(PACKAGE).pot: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST)
197+
# Convert the Vim scripts to (what looks like) Javascript
198+
$(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
199+
# create vim.pot
200+
$(XGETTEXT) --default-domain=$(PACKAGE) --add-comments \
201+
--keyword=_ --keyword=N_ --keyword=NGETTEXT:1,2 \
202+
$(PO_INPUTLIST) $(PO_VIM_JSLIST)
203+
mv -f $(PACKAGE).po $(PACKAGE).pot
204+
# Fix Vim scripts names, so that "gf" works
205+
$(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
206+
# Delete the temporary files
207+
rm *.js
167208

168209
vim.desktop: vim.desktop.in $(POFILES)
169210
echo $(LANGUAGES) | tr " " "\n" |sed -e '/\./d' | sort > LINGUAS

src/po/README.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ language.
7878

7979
(2) Translate
8080
See the gettext documentation on how to do this. You can also find
81-
examples in the other po files.
81+
examples in the other po files. You can use "gF" on the file name to see
82+
the context of the message.
8283
Search the po file for items that require translation:
8384

8485
/fuzzy\|^msgstr ""\(\n"\)\@!
@@ -123,6 +124,13 @@ language.
123124

124125
Look out for syntax errors and fix them.
125126

127+
(6) Local tryout:
128+
Vim normally picks up the .mo files from:
129+
$VIMRUNTIME/lang/{lang}/LC_MESSAGES/vim.mo
130+
To try out the messages with Vim use:
131+
make tryoutinstall
132+
And run Vim with $VIMRUNTIME set to ../runtime
133+
126134

127135
USING GETTEXT WITHOUT ICONV
128136

src/po/fixfilenames.vim

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
" Invoked with the name "vim.pot" and a list of Vim script names.
2+
" Converts them to a .js file, stripping comments, so that xgettext works.
3+
4+
set shortmess+=A
5+
6+
for name in argv()[1:]
7+
let jsname = fnamemodify(name, ":t:r") .. ".js"
8+
exe "%s+" .. jsname .. "+" .. name .. "+"
9+
endfor
10+
11+
write
12+
last
13+
quit

src/po/tojavascript.vim

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
" Invoked with the name "vim.pot" and a list of Vim script names.
2+
" Converts them to a .js file, stripping comments, so that xgettext works.
3+
" Javascript is used because, like Vim, it accepts both single and double
4+
" quoted strings.
5+
6+
set shortmess+=A
7+
8+
for name in argv()[1:]
9+
exe 'edit ' .. fnameescape(name)
10+
11+
" Strip comments
12+
g/^\s*"/s/.*//
13+
14+
" Write as .js file, xgettext recognizes them
15+
exe 'w! ' .. fnamemodify(name, ":t:r") .. ".js"
16+
endfor
17+
18+
quit

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,8 @@ static char *(features[]) =
754754

755755
static int included_patches[] =
756756
{ /* Add new patch number below this line */
757+
/**/
758+
1544,
757759
/**/
758760
1543,
759761
/**/

0 commit comments

Comments
 (0)