Bounty program for improvements to Tcl and certain Tcl packages.
Author:         Harald Oehlmann <>
State:          Final
Type:           Project
Vote:           Done
Created:        07-Dec-2017
Keywords:       msgcat, oo
Tcl-Version:    8.7


Package msgcat derives its locale search list from one specified locale by constructing a list of this locales and their precedor. This TIP proposes to allow a custom locale search list, which may contain any locale.


If one specifies a locale (example: Austrian German):

% msgcat::mclocale de_at

the locale search list is set (called 'preferences'):

% msgcat::mcpreferences
de_at de {}

So, if someone looks for a translation, they are looked up in the given order: Austrian German, German, Root:

% msgcat::mcset {} jan January
% msgcat::mc jan
% msgcat::mcset de jan Januar
% msgcat::mc jan
% msgcat::mcset de_at jan Jänner
% msgcat::mc jan

There are cases, where it is desireable to set this list to a custom list, which may not be acheved by the specification of one locale.

Use-case 1: Partial translations

I have an application, which is translated to English and German.

There is one screen, I want to translate to French (and everything else where are translations, but there are only in 3rd party packages). The masks without French translations should show the English text.

So, the desired locale search list is: "fr en {}".

Then, I can do a partial translation of some texts which will show-up in French.

Use-case 2: Mixed language regions

Regions like the Vorarlberg belong to Austria and prefer Austrian German, but the local language is closer to Swiss German.

So, their prefered search might be: "de_at de_ch de {}".

Use-case 3: Secondary language setting

An application may choose to allow the user to specify a first and 2nd language, for example French and English.

In consequence, the prefered search list is a mixure of the chosen languages: "fr en {}".


The following extensions are proposed to current msgcat 1.6.1:

Extension 1: Set the global locale search list

To set a custom locale search list, the existing command mcpreferences is extended to take arguments. If arguments are specfified, they are used to set the locale search list:

% msgcat::mcpreferences fr de {}
fr de {}

The current locale is always the first element of the locale search list (this is no change and has been always true):

% msgcat::mclocale

Setting the locale will replace a custom locale search list:

% msgcat::mclocale de
% msgcat::mcpreferences
de {}

Extension 2: Set the package locale search list

A package may also have a package locale. The extension is to support a custom package locale search list.

A custom package locale search list may be set by the extended subcommand:

% namespace eval mypack {msgcat::mcpackagelocale preferences fr de {} }
fr de {}

The package locale is always the first element of the package locale search list (custom or not):

% namespace eval mypack {msgcat::mcpackagelocale get}

A custom package locale is replaced, if a package locale is set:

% namespace eval mypack {msgcat::mcpackagelocale set de}
% namespace eval mypack {msgcat::mcpackagelocale set preferences}
de {}

A subtile difference exist between "mcpackagelocale" subcommands "set" and "preferences" with no provided arguments:

  • "mcpackagelocale set" will return the current package locale If there is no package locale activated, it will activate it with the current global preferences.
  • "mcpackagelocale preferences" will only return the current package preferences. If there is no package locale activated, it returns the global preferences.

Extension 3: Export utility function "getpreferences"

It might be useful to get the default preferences of a given locale. The corresponding internal function is now exported as:

% msgcat::mcutil getpreferences de_DE
de_de de {}

A use case is the merge of two locales to build a mixed custom locale (here a possible bilingual package for "Biel/Bienne"):

% concat [lrange [msgcat::mcutil getpreferences fr_CH] 0 end-1] [msgcat::mcutil getpreferences de_CH]
fr_ch fr de_ch de {}

Extension 4: Get the system locale

On msgcat startup, the system locale is evanluated and set. Up to now, it could only be found by "msgcat::mclocale" after startup. If it is changed, it was lost.

It is proposed to return the system locale by the command:

% msgcat::mcutil getsystemlocale


Compatibility issues arise, if a package expects, that exactly one catalog file is loaded, if it has only first level message files.

With this extension, multiple first-level message files may be loaded.


The implementation is in tcl fossil in branch tip499-msgcat-custom-preferences.

There are tests but no man page jet. Please use this text as man-page.


This document has been placed in the public domain.