>>> Please note that you have to handle not only format-strings of >>> ‘message’, but also ‘error’ and even more low-level ‘format’, i.e. all >>> these (error STRING &rest ARGS) (message FORMAT-STRING &rest ARGS) >>> (format-message STRING &rest OBJECTS) (format STRING &rest OBJECTS) >>> >> I expect that 'format' won't translate its first argument, whereas >> 'error', 'message', and 'format-message' will. This will be for the same >> reason that 'format' does not translate quotes. > > Then it should be sufficient to add a gettext call to 'format-message' only, > because all other related functions 'message', 'error', 'tramp-message', > 'tramp-error', etc. all they use 'format-message' directly or indirectly. Maybe I'm too stupid to comprehend the complexity of this task in its entirety, but I tried to install gettext infrastructure in Emacs with gettextize, and then tried to run xgettext on source code, and see no technical problems. What I tried is to run this command, and it extracts all messages: xgettext --from-code=UTF-8 -kformat-message -kmessage -kerror -ktramp-message -ktramp-error *.el then this command extracts all Gnus messages into a separate file: xgettext --from-code=UTF-8 -kformat-message -kmessage -kerror gnus/*.el -o gnus_messages.po this command extracts all menu items: xgettext --from-code=UTF-8 -kmenu-item *.el **/*.el -o menus.po and this extracts all docstrings: xgettext --from-code=UTF-8 -kdefcustom:3 -kdefvar:3 -kdefun:3 *.el **/*.el -o docstrings.po The size of docstrings.po is about 9MB, so perhaps it should reside in a separate catalog defined by e.g. (defdomain emacs-docstrings with semantics similar to defgroup, but I have no opinion about this. I think this project urgently needs a coordinator: to negotiate with package authors and translation teams about how to better split translations to message catalogs. So there are not so much technical problems, but mostly organizational ones. > IIUC, using standard gettext functions this would rather correspond to > > (message (ngettext "Replaced %1$d occurrence%s" > "Replaced %1$d occurrences%s" > replace-count) It seems better to start with this standard function and add more optimizations like ‘nmessage’ later. Other Lisp implementations use ‘ngettext’ as well, e.g.: https://clisp.sourceforge.io/impnotes.html#ggettext So I'm going to start with more obvious parts of the task by fixing the current bugs of incorrect English syntax in a forward-compatible way: