Config

The config is the actual feature to make this program is different than other programs: I allow user to write config in python, which provide more flexible and free method to customization. See file location to know where is the config. The file location usually respect standard of every OS (history file is similar):

  • GNU/Linux, Android (Termux), Windows (Msys2, Cygwin): ${XDG_CONFIG_HOME:-$HOME/.config}/translate-shell/config.py

  • Windows (native): %APPDATA%\Local\translate-shell\config.py

  • macOS: $HOME/Library/translate-shell/config.py

  • dropdown: $HOME/.translate-shell/config.py

This is a implementation of https://github.com/felixonmars/ydcv/issues/55.

the config file must have a function named configure() which input nothing and return a Configuration object. An example is as following:

"""Configure."""

from translate_shell.config import Configuration


def configure() -> Configuration:
    """Configure.

    :rtype: Configuration
    """
    config = Configuration()
    config.target_lang = "zh_CN"
    config.translators = "google,speaker"
    return config

If you have a completion provided by LSP, you can see which attribute can be defined:

CLI Options’ Default Values

By default, trans is trans --source-lang=auto --target-lang=auto --engines=google --format=text --clipboard. You can change it in config. About options’ meanings, you can see options. About all options’ values, you can see trans --print-setting.

# telling translator the source language is faster than let translator detect
config.source_lang = "en"
# target_lang by default is 'auto' which will detect `$LANG`. see `locale`
config.target_lang = "zh_CN"
config.translators = "google,bing,haici"
# Usually you don't need it
config.format = "json"
# Disable translate clipboard automatically
config.clipboard = False
# Disable notification of translation automatically
config.notification = False
# Translate clipboard every 0.5 seconds
config.sleep_seconds = 0.5
# GUI translation window duration time
config.duration = 20

Logger

By default, python’s logging is very ugly:

>>> import logging
>>> logging.warning("This is a warning!")
WARNING:root:This is a warning!

I advise rich:

>>> import logging
>>> from rich.logging import RichHandler
>>> logging.basicConfig(
...     level="INFO",
...     format="%(message)s",
...     handlers=[RichHandler(rich_tracebacks=True, markup=True)],
...     force=True,
... )
>>> logging.warning("This is a warning!")
[11/30/22 07:40:02] WARNING  This is a warning!              <stdin>:1

The log has color (different from log level), time, filename and linenumber! The warning is red and the info is blue. Great!

color

Default level is WARNING, which make logger.info will not display. Change it to INFO by trans --verbose or level="INFO" in config.py.

Options

有道智云

Some online translator need user to input a APP ID and secret. However, put these information in configuration file directly is unsafe. Some user know chmod 600, it is good, however, I can provide a better solution. Let us take youdaozhiyun as an example:

Quoted from ydcv

翻译实例-创建实例-选”文本翻译”, 我的应用-创建应用-接入方式:API-选择绑定刚才 创建的自然语言翻译服务-文本翻译实例。 得到的应用 ID / 应用密钥即为本工具的 YDAPPID/YDAPPSEC。

By default, this package get YDAPPID, YDAPPSEC from keyring which allows user to encrypt password. Create two passwords:

keyring set youdaozhiyun appid XXX
keyring set youdaozhiyun appsec YYY

This is an implementation of https://github.com/felixonmars/ydcv/issues/76.

If you want same behavior as ydcv, try:

import os

config.options = {}
config.options["youdaozhiyun"] = {}


def get_youdaozhiyun_app_info() -> tuple[str, str]:
    return os.getenv("YDAPPID", ""), os.getenv("YDAPPSEC", "")


config.options["youdaozhiyun"]["get_youdaozhiyun_app_info"] = get_youdaozhiyun_app_info

OpenAI

config.options = {}
config.options["openai"] = {}
config.options["openai"]["model"] = "gpt-3.5-turbo"

LLaMa

import os

from llama_cpp import Llama

config.options = {}
config.options["llama"] = {}
config.options["llama"]["model"] = Llama(
    os.path.expanduser("~/.local/share/translate-shell/model.bin")
)

Speaker

See speaker

config.options = {}
config.options["speaker"] = {}


def get_speaker(query: str) -> list[str]:
    return ["espeak", query]


config.options["speaker"]["get_speaker"] = get_speaker

Stardict

Default value can be seen by trans --print-setting dictionary_dirs.

config.options = {}
config.options["stardict"] = {}
config.options["stardict"]["stardict"] = {
    "en": {"zh_CN": ["my-favorite-dictionary", "my-backup-dictionary"]}
}

Prompt

Default prompt string style is inspired by powerlevel10k. You need install some requirements to provide color and fonts. All screenshots are using JetBrainsMono Nerd Font Mono.

You can customize config.get_prompt:

from translate_shell.utils.prompt import process_clipboard

def get_prompt(text, tl, sl, translators)
    prompt = sl + ":" + tl + "> "
    return process_clipboard(text, prompt)

config.get_prompt = get_prompt

It will give you like

$ trans
auto:zh_CN>

The screenshot is same as above in logger.

The functions in section should be useful for customization. BTW, you can use these functions to define your prompt of python, too. See prompt.

python

Process Input

Magic text

Any user who comes from translate-shell (awk) know it has an interesting function, that is user can input en:zh_CN to change source language and target language. I can it magic text: any text will be truly translated. I want to provide user more freedom. By default, we have the following magic texts:

  • sl:tl can change source language and target language. sl: and :tl is same.

  • : will swap source language and target language.

  • =translator1,translator2,... will change translators.

  • = will display current translators.

  • !XXX will execute XXX in shell command.

  • ! will execute $SHELL or sh if $SHELL is not exist.

  • <filename will translate file contents.

Some magic texts are inspired by shell.

Preprocess

And we will preprocess the non-magic text:

  • convert \t to ‘ ‘, useful for translate programming variables

  • strip trailing whitespaces, reduce length due to limitation of some translation engines

  • strip redundant whitespaces, reduce length due to limitation of some translation engines

  • remove -\n, useful for reading pdf

  • convert \n to ‘ ‘, useful for reading pdf

  • change get_char to get char, useful for translate programming variables

  • change getChar to get char, useful for translate programming variables

  • lowercase, useful for translate programming variables

Refer https://github.com/felixonmars/ydcv/issues/67:

paper

The clipboard get

Some earlier results suggest\n that incorporating local normalization in linear block transform coding methods can improve cod-\n ing performance

If we don’t preprocess text, the result of youdaozhiyun will be:

一些早期的结果表明\n 在线性分块变换编码方法中加入局部归一化可以提高编码质量\n 荷兰国际集团(ing)性能

It is not your need, I believe.

After preprocess:

Some earlier results suggest that incorporating local normalization in linear block transform coding methods can improve coding performance

The result is your need:

一些早期的研究结果表明,在线性块变换编码方法中加入局部归一化可以提高编码性能

This PR has been ignored by the author, so I have to create this software for myself.

You can customize config.process_input.

Process output

You can customize config.process_output. Same as prompt, a p10k output style has been provided.

You can customize config.process_output:

def process_output(translations):
    text = "\n".join(
        "\n".join(
            [rst.translator + ":", rst.paraphrase + rst.phonetic]
            + [k + " " + v for k, v in rst.explains.items()]
        )
        for rst in translations.results
    )
    return text


config.process_output = process_output

The screenshot is same as above in logger.

The functions in section should be useful for customization.

If you install wakatime/repl-python-wakatime and wakatime/wakatime-cli, default process_output() will call wakatime_hook() to record your translating time in wakatime.

Translate Clipboard

In REPL, translate-shell can translate any content in clipboard, when it has changed.

You can customize config.get_clipper.

Notify

See GUI.

You can customize config.notify.

Readline Complete

See readline

You can customize config.complete.