Repository: tldr-pages/tldr-python-client (language: python)

Issue:
Feature Proposal: Custom default language
Hi, I just discovered your project and think this would be a useful feature:
A `TLDR_LANGUAGE` environment variable that sets the default language for tldr. This way, users who want tldr to use a different language by default than the system language can set it permanently in their  `~/.bashrc`.
I would be happy to write the changes myself, I'd just like to know if that feature would be welcome or not.


Discussion / hints:
I have no qualms with adding this. I think it would follow the `LANG` specification (e.g. a singular 4 character language code to use) and that the language look-up would be to prepend `TLDR_LANGUAGE` environment variable to the language list look-up that is derived as part of the [client specification](https://github.com/tldr-pages/tldr/blob/main/CLIENT-SPECIFICATION.md#language).

Implementation would be (I think) to modify the [`get_language_list`](https://github.com/tldr-pages/tldr-python-client/blob/main/tldr.py#L186) function to do this check and prepend and also [`get_default_langauge`](https://github.com/tldr-pages/tldr-python-client/blob/main/tldr.py#L62) function so that it gets returned instead `LANG` if set.
As a matter of fact, I don't believe this client is even complying with the spec until this is fixed.

>If a client has access to environment variables, it MUST use them derive the preferred user language as described in the next paragraphs.
@bl-ue The spec prescribes only usage of the `LANG` and `LANGUAGE` environment variables as being used to determine language, which this client does do and is spec compliant.

Adding support for `TLDR_LANGUAGE` would if anything make the client less spec compliant, but I think it's a useful feature, and one that can be used as an implementation reference to perhaps adopting into the spec (or at the very least add language to the spec allowing this modification).
Oh, I see.  I thought that `TLDR_LANGUAGE` was merely a suggestion.  @nebnola are you aware that you can set `LANG=de` (for example) to customize the default language that `tldr` uses?
Yes, I'm aware of that. However `LANG` affects the whole system, while I would like to be able to set a default for tldr without specifying the `-L` argument each time. So basically, if `-L` is unset, as @MasterOdin said, I would prepend the value of `TLDR_LANGUAGE` to the existing list which is derived from `LANG`and `LANGUAGES`
Hm, thinking about it, I think that you want to modify the `get_language_list` function to prepend the value of `TLDR_LANGUAGE` and modify here:

https://github.com/tldr-pages/tldr-python-client/blob/f24f81fb01d2b1bb69840bc6f98921fcbd700033/tldr.py#L340-L341

so that it first calls a function that returns the value of `TLDR_LANGUAGE`, and if that's not set, then it calls `get_default_language`, or something of that nature. We would ideally keep the behavior of appending `LANG` into `LANGUAGES` if both are set, but still allow the usage of `TLDR_LANGUAGE` as the principal language if set.

Hopefully that makes sense.

Fix patch:
diff --git a/README.md b/README.md
index c85e305..31fa5b0 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,7 @@ export TLDR_COLOR_DESCRIPTION="white"
 export TLDR_COLOR_EXAMPLE="green"
 export TLDR_COLOR_COMMAND="red"
 export TLDR_COLOR_PARAMETER="white"
+export TLDR_LANGUAGE="es"
 export TLDR_CACHE_ENABLED=1
 export TLDR_CACHE_MAX_AGE=720
 export TLDR_PAGES_SOURCE_LOCATION="https://raw.githubusercontent.com/tldr-pages/tldr/master/pages"
@@ -120,12 +121,14 @@ Any of the values of above may be omitted. For example, you can do similar thing
 
 The language that tldr will use is dependent on a number of factors. If you specify a language via the
 `--language` flag, tldr will attempt to use that language and only that language. Otherwise, it will
-default to language set using `LANGUAGE` and `LANG` (ignoring the value `C` and `POSIX`).
+try to use the language specified by `TLDR_LANGUAGE`. If it is not set, or the page does not exist in that language,
+then tldr will use the
+language set using `LANGUAGE` and `LANG` (ignoring the values `C` and `POSIX`).
 If neither are set, then tldr will always attempt to get the `en` page. Finally, if `LANG` is set, it uses `LANGUAGE`, if set,
 first as the priority list to try languages in, followed by `LANG` if not included in `LANGUAGE`
 and `en` as fallback (assuming it does not already appear somewhere in `LANGUAGE` or `LANG`).
 All language values should be set to a value that follows [RFC 1766](https://tools.ietf.org/html/rfc1766.html),
-with the special exception of `C` and `POSIX` which is ignored.
+with the special exceptions of `C` and `POSIX` which are ignored.
 
 ### Remote source
 
diff --git a/tldr.py b/tldr.py
index c8089ca..74bcb6b 100755
--- a/tldr.py
+++ b/tldr.py
@@ -184,6 +184,7 @@ def get_platform_list():
 
 
 def get_language_list():
+    tldr_language = get_language_code(os.environ.get('TLDR_LANGUAGE', ''))
     languages = os.environ.get('LANGUAGE', '').split(':')
     languages = list(map(
         get_language_code,
@@ -192,12 +193,19 @@ def get_language_list():
 
     default_lang = get_default_language()
 
-    if default_lang is not None and default_lang not in languages:
-        languages.append(default_lang)
-    else:
+    if default_lang is None:
         languages = []
+    elif default_lang not in languages:
+        languages.append(default_lang)
+    if tldr_language:
+        # remove tldr_language if it already exists to avoid double entry
+        try:
+            languages.remove(tldr_language)
+        except ValueError:
+            pass
+        languages.insert(0, tldr_language)
     if 'en' not in languages:
-        languages.append(None)
+        languages.append('en')
     return languages
 
 
@@ -338,8 +346,8 @@ def output(page):
 
 def update_cache(language=None):
     if language is None:
-        default_lang = get_default_language()
-        language = default_lang if default_lang is not None else 'en'
+        tldr_language = os.environ.get("TLDR_LANGUAGE", get_default_language())
+        language = tldr_language if tldr_language else 'en'
     elif isinstance(language, list):
         language = language[0]
     try:


Test patch:
diff --git a/tests/test_tldr.py b/tests/test_tldr.py
index cd07622..0f4f914 100644
--- a/tests/test_tldr.py
+++ b/tests/test_tldr.py
@@ -61,6 +61,23 @@ def test_get_default_language_unset(monkeypatch):
     assert tldr.get_default_language() is None
 
 
+@pytest.mark.parametrize("tldr_language, language, lang, expected", [
+    ("en", None, "fr_FR", ["en", "fr"]),
+    ("de", "ja_JA:cz_CZ", "cz_CZ", ["de", "ja", "cz", "en"]),
+    ("it", None, "C", ["it", "en"]),
+])
+def test_tldr_language(tldr_language, language, lang, expected, monkeypatch):
+    for name, var in [("TLDR_LANGUAGE", tldr_language),
+                      ("LANGUAGE", language),
+                      ("LANG", lang)]:
+        # Unset environment variable if their value is given as None
+        if var is None:
+            monkeypatch.delenv(name, raising=False)
+        else:
+            monkeypatch.setenv(name, var)
+    assert tldr.get_language_list() == expected
+
+
 @pytest.mark.parametrize("platform, expected", [
     ("linux2", "linux"),
     ("win32", "windows"),