Skip to content

Commit

Permalink
patch 8.2.1544: cannot translate messages in a Vim script
Browse files Browse the repository at this point in the history
Problem:    Cannot translate messages in a Vim script.
Solution:   Add gettext().  Try it out for a few messages in the options
            window.
  • Loading branch information
brammool committed Aug 30, 2020
1 parent 25859dd commit 0b39c3f
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 15 deletions.
2 changes: 2 additions & 0 deletions Filelist
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,8 @@ LANG_SRC = \
src/po/README_mvc.txt \
src/po/check.vim \
src/po/cleanup.vim \
src/po/tojavascript.vim \
src/po/fixfilenames.vim \
src/po/Makefile \
src/po/Make_all.mak \
src/po/Make_cyg.mak \
Expand Down
14 changes: 14 additions & 0 deletions runtime/doc/eval.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2546,6 +2546,7 @@ gettabvar({nr}, {varname} [, {def}])
gettabwinvar({tabnr}, {winnr}, {name} [, {def}])
any {name} in {winnr} in tab page {tabnr}
gettagstack([{nr}]) Dict get the tag stack of window {nr}
gettext({text}) String lookup translation of {text}
getwininfo([{winid}]) List list of info about each window
getwinpos([{timeout}]) List X and Y coord in pixels of the Vim window
getwinposx() Number X coord in pixels of the Vim window
Expand Down Expand Up @@ -5827,6 +5828,19 @@ gettagstack([{nr}]) *gettagstack()*
Can also be used as a |method|: >
GetWinnr()->gettagstack()


gettext({text}) *gettext()*
Translate {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.
For {text} double quoted strings are preferred, because
xgettext does not understand escaping in single quoted
strings.


getwininfo([{winid}]) *getwininfo()*
Returns information about windows as a |List| with Dictionaries.

Expand Down
1 change: 1 addition & 0 deletions runtime/doc/usr_41.txt
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@ String manipulation: *string-functions*
execute() execute an Ex command and get the output
win_execute() like execute() but in a specified window
trim() trim characters from a string
gettext() lookup message translation

List manipulation: *list-functions*
get() get an item without error for wrong index
Expand Down
16 changes: 8 additions & 8 deletions runtime/optwin.vim
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
" These commands create the option window.
"
" Maintainer: Bram Moolenaar <[email protected]>
" Last Change: 2020 Jun 10
" Last Change: 2020 aug 30

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

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

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

Expand Down
22 changes: 22 additions & 0 deletions src/evalfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ static void f_getreg(typval_T *argvars, typval_T *rettv);
static void f_getreginfo(typval_T *argvars, typval_T *rettv);
static void f_getregtype(typval_T *argvars, typval_T *rettv);
static void f_gettagstack(typval_T *argvars, typval_T *rettv);
static void f_gettext(typval_T *argvars, typval_T *rettv);
static void f_haslocaldir(typval_T *argvars, typval_T *rettv);
static void f_hasmapto(typval_T *argvars, typval_T *rettv);
static void f_hlID(typval_T *argvars, typval_T *rettv);
Expand Down Expand Up @@ -667,6 +668,7 @@ static funcentry_T global_functions[] =
{"gettabvar", 2, 3, FEARG_1, ret_any, f_gettabvar},
{"gettabwinvar", 3, 4, FEARG_1, ret_any, f_gettabwinvar},
{"gettagstack", 0, 1, FEARG_1, ret_dict_any, f_gettagstack},
{"gettext", 1, 1, FEARG_1, ret_string, f_gettext},
{"getwininfo", 0, 1, FEARG_1, ret_list_dict_any, f_getwininfo},
{"getwinpos", 0, 1, FEARG_1, ret_list_number, f_getwinpos},
{"getwinposx", 0, 0, 0, ret_number, f_getwinposx},
Expand Down Expand Up @@ -3437,6 +3439,26 @@ f_gettagstack(typval_T *argvars, typval_T *rettv)
get_tagstack(wp, rettv->vval.v_dict);
}

/*
* "gettext()" function
*/
static void
f_gettext(typval_T *argvars, typval_T *rettv)
{
if (argvars[0].v_type != VAR_STRING
|| argvars[0].vval.v_string == NULL
|| *argvars[0].vval.v_string == NUL)
{
semsg(_(e_invarg2), tv_get_string(&argvars[0]));
}
else
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = vim_strsave(
(char_u *)_(argvars[0].vval.v_string));
}
}

// for VIM_VERSION_ defines
#include "version.h"

Expand Down
53 changes: 47 additions & 6 deletions src/po/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ all: $(MOFILES) $(MOCONVERTED) $(MSGFMT_DESKTOP)

check: $(CHECKFILES)

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

# installing for local tryout into ../../runtime/lang
tryoutinstall: $(MOFILES) $(MOCONVERTED)
@$(MAKE) prefixcheck
for lang in $(LANGUAGES); do \
dir=../../runtime/lang/$$lang/; \
if test ! -x "$$dir"; then \
mkdir $$dir; chmod 755 $$dir; \
fi; \
dir=../../runtime/lang/$$lang/LC_MESSAGES; \
if test ! -x "$$dir"; then \
mkdir $$dir; chmod 755 $$dir; \
fi; \
if test -r $$lang.mo; then \
cp $$lang.mo $$dir/$(PACKAGE).mo; \
chmod 644 $$dir/$(PACKAGE).mo; \
fi; \
done

converted: $(MOCONVERTED)

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

$(PACKAGE).pot: ../*.c ../if_perl.xs ../GvimExt/gvimext.cpp ../globals.h ../if_py_both.h ../vim.h gvim.desktop.in vim.desktop.in
cd ..; $(XGETTEXT) --default-domain=$(PACKAGE) \
--add-comments --keyword=_ --keyword=N_ --keyword=NGETTEXT:1,2 \
*.c if_perl.xs GvimExt/gvimext.cpp globals.h if_py_both.h vim.h \
po/gvim.desktop.in po/vim.desktop.in
mv -f ../$(PACKAGE).po $(PACKAGE).pot
PO_INPUTLIST = \
../*.c \
../if_perl.xs \
../GvimExt/gvimext.cpp \
../globals.h \
../if_py_both.h \
../vim.h \
gvim.desktop.in \
vim.desktop.in

PO_VIM_INPUTLIST = \
../../runtime/optwin.vim

PO_VIM_JSLIST = \
optwin.js

$(PACKAGE).pot: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST)
# Convert the Vim scripts to (what looks like) Javascript
$(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
# create vim.pot
$(XGETTEXT) --default-domain=$(PACKAGE) --add-comments \
--keyword=_ --keyword=N_ --keyword=NGETTEXT:1,2 \
$(PO_INPUTLIST) $(PO_VIM_JSLIST)
mv -f $(PACKAGE).po $(PACKAGE).pot
# Fix Vim scripts names, so that "gf" works
$(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
# Delete the temporary files
rm *.js

vim.desktop: vim.desktop.in $(POFILES)
echo $(LANGUAGES) | tr " " "\n" |sed -e '/\./d' | sort > LINGUAS
Expand Down
10 changes: 9 additions & 1 deletion src/po/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ language.

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

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

Look out for syntax errors and fix them.

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


USING GETTEXT WITHOUT ICONV

Expand Down
13 changes: 13 additions & 0 deletions src/po/fixfilenames.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
" Invoked with the name "vim.pot" and a list of Vim script names.
" Converts them to a .js file, stripping comments, so that xgettext works.

set shortmess+=A

for name in argv()[1:]
let jsname = fnamemodify(name, ":t:r") .. ".js"
exe "%s+" .. jsname .. "+" .. name .. "+"
endfor

write
last
quit
18 changes: 18 additions & 0 deletions src/po/tojavascript.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
" Invoked with the name "vim.pot" and a list of Vim script names.
" Converts them to a .js file, stripping comments, so that xgettext works.
" Javascript is used because, like Vim, it accepts both single and double
" quoted strings.

set shortmess+=A

for name in argv()[1:]
exe 'edit ' .. fnameescape(name)

" Strip comments
g/^\s*"/s/.*//

" Write as .js file, xgettext recognizes them
exe 'w! ' .. fnamemodify(name, ":t:r") .. ".js"
endfor

quit
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1544,
/**/
1543,
/**/
Expand Down

0 comments on commit 0b39c3f

Please sign in to comment.