To: vim_dev@googlegroups.com Subject: Patch 8.2.1544 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1544 Problem: Cannot translate messages in a Vim script. Solution: Add gettext(). Try it out for a few messages in the options window. Files: Filelist, src/po/Makefile, src/po/README.txt, runtime/optwin.vim, src/evalfunc.c, src/po/tojavascript.vim, src/po/fixfilenames.vim, runtime/doc/eval.txt, runtime/doc/usr_41.txt *** ../vim-8.2.1543/Filelist 2020-08-29 16:40:22.497472241 +0200 --- Filelist 2020-08-30 15:46:28.551121452 +0200 *************** *** 1028,1033 **** --- 1028,1035 ---- 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 \ *** ../vim-8.2.1543/src/po/Makefile 2019-11-14 21:35:21.000000000 +0100 --- src/po/Makefile 2020-08-30 15:30:13.297825887 +0200 *************** *** 36,41 **** --- 36,42 ---- check: $(CHECKFILES) + # installing for real install: $(MOFILES) $(MOCONVERTED) @$(MAKE) prefixcheck for lang in $(LANGUAGES); do \ *************** *** 61,66 **** --- 62,85 ---- 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 *************** *** 158,169 **** 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 vim.desktop: vim.desktop.in $(POFILES) echo $(LANGUAGES) | tr " " "\n" |sed -e '/\./d' | sort > LINGUAS --- 177,210 ---- checkclean: rm -f *.ck ! 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 *** ../vim-8.2.1543/src/po/README.txt 2019-03-07 12:24:01.000000000 +0100 --- src/po/README.txt 2020-08-30 15:44:35.915435739 +0200 *************** *** 78,84 **** (2) Translate See the gettext documentation on how to do this. You can also find ! examples in the other po files. Search the po file for items that require translation: /fuzzy\|^msgstr ""\(\n"\)\@! --- 78,85 ---- (2) Translate See the gettext documentation on how to do this. You can also find ! 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"\)\@! *************** *** 123,128 **** --- 124,136 ---- 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 *** ../vim-8.2.1543/runtime/optwin.vim 2019-11-07 21:34:47.000000000 +0100 --- runtime/optwin.vim 2020-08-30 15:39:54.368220034 +0200 *************** *** 1,7 **** " These commands create the option window. " " Maintainer: Bram Moolenaar ! " Last Change: 2019 Nov 07 " If there already is an option window, jump to that one. let buf = bufnr('option-window') --- 1,7 ---- " These commands create the option window. " " Maintainer: Bram Moolenaar ! " Last Change: 2020 aug 30 " If there already is an option window, jump to that one. let buf = bufnr('option-window') *************** *** 145,157 **** 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 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 .') ! call append(4, '" Hit on a help line to open a help window on this option.') ! call append(5, '" Hit on an index line to jump there.') ! call append(6, '" Hit on a "set" line to refresh it.') " These functions are called often below. Keep them fast! --- 145,157 ---- setlocal ts=15 tw=0 noro buftype=nofile " Insert help and a "set" command for each option. ! call append(0, gettext('" Each "set" line shows the current value of an option (on the left).')) ! call append(1, gettext('" Hit 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 .')) ! call append(4, gettext('" Hit on a help line to open a help window on this option.')) ! call append(5, gettext('" Hit on an index line to jump there.')) ! call append(6, gettext('" Hit on a "set" line to refresh it.')) " These functions are called often below. Keep them fast! *************** *** 447,452 **** --- 447,455 ---- call append("$", "spellcapcheck\tpattern to locate the end of a sentence") call append("$", "\t(local to buffer)") call OptionL("spc") + call append("$", "spelloptions\tflags to change how spell checking works") + call append("$", "\t(local to buffer)") + call OptionL("spo") call append("$", "spellsuggest\tmethods used to suggest corrections") call OptionG("sps", &sps) call append("$", "mkspellmem\tamount of memory used by :mkspell before compressing") *************** *** 1153,1159 **** if has("quickfix") ! call Header("running make and jumping to errors") call append("$", "errorfile\tname of the file that contains error messages") call OptionG("ef", &ef) call append("$", "errorformat\tlist of formats for error messages") --- 1156,1162 ---- if has("quickfix") ! call Header("running make and jumping to errors (quickfix)") call append("$", "errorfile\tname of the file that contains error messages") call OptionG("ef", &ef) call append("$", "errorformat\tlist of formats for error messages") *************** *** 1174,1179 **** --- 1177,1184 ---- call append("$", "makeencoding\tencoding of the \":make\" and \":grep\" output") call append("$", "\t(global or local to buffer)") call OptionG("menc", &menc) + call append("$", "quickfixtextfunc\tfunction to display text in the quickfix window") + call OptionG("qftf", &qftf) endif *** ../vim-8.2.1543/src/evalfunc.c 2020-08-28 22:24:40.660494318 +0200 --- src/evalfunc.c 2020-08-30 14:43:31.912730184 +0200 *************** *** 97,102 **** --- 97,103 ---- 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); *************** *** 667,672 **** --- 668,674 ---- {"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}, *************** *** 3437,3442 **** --- 3439,3464 ---- 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" *** ../vim-8.2.1543/src/po/tojavascript.vim 2020-08-30 15:46:46.503071352 +0200 --- src/po/tojavascript.vim 2020-08-30 14:59:11.826797027 +0200 *************** *** 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 *** ../vim-8.2.1543/src/po/fixfilenames.vim 2020-08-30 15:46:46.507071343 +0200 --- src/po/fixfilenames.vim 2020-08-30 14:30:37.390736563 +0200 *************** *** 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 *** ../vim-8.2.1543/runtime/doc/eval.txt 2020-08-28 22:24:40.656494333 +0200 --- runtime/doc/eval.txt 2020-08-30 14:50:30.472032635 +0200 *************** *** 2534,2539 **** --- 2547,2553 ---- 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 *************** *** 5790,5806 **** Can also be used as a |method|: > GetWinnr()->gettagstack() getwininfo([{winid}]) *getwininfo()* ! Returns information about windows as a List with Dictionaries. If {winid} is given Information about the window with that ID ! is returned. If the window does not exist the result is an ! empty list. Without {winid} information about all the windows in all the tab pages is returned. ! Each List item is a Dictionary with the following entries: botline last displayed buffer line bufnr number of buffer in the window height window height (excluding winbar) --- 5830,5859 ---- 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. If {winid} is given Information about the window with that ID ! is returned, as a |List| with one item. If the window does not ! exist the result is an empty list. Without {winid} information about all the windows in all the tab pages is returned. ! Each List item is a |Dictionary| with the following entries: botline last displayed buffer line bufnr number of buffer in the window height window height (excluding winbar) *** ../vim-8.2.1543/runtime/doc/usr_41.txt 2020-08-28 22:24:40.660494318 +0200 --- runtime/doc/usr_41.txt 2020-08-30 14:57:47.935010909 +0200 *************** *** 620,625 **** --- 628,634 ---- 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 *** ../vim-8.2.1543/src/version.c 2020-08-30 12:54:49.849096734 +0200 --- src/version.c 2020-08-30 15:43:02.447696317 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1544, /**/ -- Experience is what you get when you don't get what you want. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///