]> granicus.if.org Git - vim/commitdiff
patch 8.2.1544: cannot translate messages in a Vim script v8.2.1544
authorBram Moolenaar <Bram@vim.org>
Sun, 30 Aug 2020 13:52:10 +0000 (15:52 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 30 Aug 2020 13:52:10 +0000 (15:52 +0200)
Problem:    Cannot translate messages in a Vim script.
Solution:   Add gettext().  Try it out for a few messages in the options
            window.

Filelist
runtime/doc/eval.txt
runtime/doc/usr_41.txt
runtime/optwin.vim
src/evalfunc.c
src/po/Makefile
src/po/README.txt
src/po/fixfilenames.vim [new file with mode: 0644]
src/po/tojavascript.vim [new file with mode: 0644]
src/version.c

index 42eaa1d3edd7079a997c83c40fbc35664a3ae3df..cd1325f30e081bef023101e176b56e4e0f028f6a 100644 (file)
--- a/Filelist
+++ b/Filelist
@@ -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 \
index e0c84730380ea1901ce09a4f8382fe6fcb5f1e1b..f1b699219649038c550992a933f9e944c9b23ae6 100644 (file)
@@ -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
@@ -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.
 
index 10e53baf7233f7a2ad0e0aa296a5f1fa251cb0cd..81474c7f42c1f453e3dc42cd031d007a6a58750a 100644 (file)
@@ -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
index 5bb78cdb0a52bf3eac3670441be2dfd559dfafd1..67601a842276761e88f660067f920af185cda0e5 100644 (file)
@@ -1,7 +1,7 @@
 " These commands create the option window.
 "
 " Maintainer:  Bram Moolenaar <Bram@vim.org>
-" 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')
@@ -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!
 
index 62bbb8888d52d4ac1599beae0271d9f1a46cff8e..fff7a89a9aa856eca7c01e023df6406348b18077 100644 (file)
@@ -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);
@@ -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},
@@ -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"
 
index cce14a94a3bbb6fbca00623ba007b1258735d86c..8ef93e6eb0fc52b6b41a8f3b200814bae84f45ba 100644 (file)
@@ -36,6 +36,7 @@ all: $(MOFILES) $(MOCONVERTED) $(MSGFMT_DESKTOP)
 
 check: $(CHECKFILES)
 
+# installing for real
 install: $(MOFILES) $(MOCONVERTED)
        @$(MAKE) prefixcheck
        for lang in $(LANGUAGES); do \
@@ -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
@@ -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
index e60d1d21683ab52b205c0275c4425573cde5fe6c..68d267af17d36f1489dc3b24f48167bbe7e625be 100644 (file)
@@ -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"\)\@!
@@ -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
 
diff --git a/src/po/fixfilenames.vim b/src/po/fixfilenames.vim
new file mode 100644 (file)
index 0000000..65d448c
--- /dev/null
@@ -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
diff --git a/src/po/tojavascript.vim b/src/po/tojavascript.vim
new file mode 100644 (file)
index 0000000..7868570
--- /dev/null
@@ -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
index 8eaf4844772a8b6983c9af0985d16e17bc32f710..1fe5b26dfd232c5310de22b715782b99b62465ab 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1544,
 /**/
     1543,
 /**/