{"id":14964843,"url":"https://github.com/freed-wu/translate-shell","last_synced_at":"2025-04-07T12:04:07.392Z","repository":{"id":64126665,"uuid":"573625035","full_name":"Freed-Wu/translate-shell","owner":"Freed-Wu","description":"Translate text by google, bing, youdaozhiyun, haici, stardict, openai, large language model of local machine, etc at same time from CLI, GUI (GNU/Linux, Android, macOS and Windows), REPL, python, shell and vim.","archived":false,"fork":false,"pushed_at":"2025-03-24T18:18:12.000Z","size":463,"stargazers_count":38,"open_issues_count":6,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-28T16:40:33.032Z","etag":null,"topics":["bing","chatgpt","commandline-tool","google","haici","lftp","llama","llamacpp","lsp-server","openai","prompt","python","repl","shell","stardict","translate","vim","youdao"],"latest_commit_sha":null,"homepage":"https://translate-shell.readthedocs.io/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Freed-Wu.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"patreon":"user?u=83975719","custom":["https://user-images.githubusercontent.com/32936898/199681341-1c5cfa61-4411-4b67-b268-7cd87c5867bb.png","https://user-images.githubusercontent.com/32936898/199681363-1094a0be-85ca-49cf-a410-19b3d7965120.png","https://user-images.githubusercontent.com/32936898/199681368-c34c2be7-e0d8-43ea-8c2c-d3e865da6aeb.png"]}},"created_at":"2022-12-02T23:30:38.000Z","updated_at":"2025-03-06T07:39:15.000Z","dependencies_parsed_at":"2024-01-01T19:29:55.000Z","dependency_job_id":"454e54b1-3beb-4a2d-9293-cc4985221c3d","html_url":"https://github.com/Freed-Wu/translate-shell","commit_stats":{"total_commits":159,"total_committers":5,"mean_commits":31.8,"dds":0.07547169811320753,"last_synced_commit":"4f9ed84cd915ef82be96abefdf473c0207edd311"},"previous_names":[],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Freed-Wu%2Ftranslate-shell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Freed-Wu%2Ftranslate-shell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Freed-Wu%2Ftranslate-shell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Freed-Wu%2Ftranslate-shell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Freed-Wu","download_url":"https://codeload.github.com/Freed-Wu/translate-shell/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246457966,"owners_count":20780676,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bing","chatgpt","commandline-tool","google","haici","lftp","llama","llamacpp","lsp-server","openai","prompt","python","repl","shell","stardict","translate","vim","youdao"],"created_at":"2024-09-24T13:33:51.356Z","updated_at":"2025-03-31T11:01:55.171Z","avatar_url":"https://github.com/Freed-Wu.png","language":"Python","readme":"# translate-shell\n\n[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/Freed-Wu/translate-shell/main.svg)](https://results.pre-commit.ci/latest/github/Freed-Wu/translate-shell/main)\n[![github/workflow](https://github.com/Freed-Wu/translate-shell/actions/workflows/main.yml/badge.svg)](https://github.com/Freed-Wu/translate-shell/actions)\n[![codecov](https://codecov.io/gh/Freed-Wu/translate-shell/branch/main/graph/badge.svg)](https://codecov.io/gh/Freed-Wu/translate-shell)\n[![readthedocs](https://shields.io/readthedocs/translate-shell)](https://translate-shell.readthedocs.io)\n[![DeepSource](https://deepsource.io/gh/Freed-Wu/translate-shell.svg/?show_trend=true)](https://deepsource.io/gh/Freed-Wu/translate-shell)\n\n[![github/downloads](https://shields.io/github/downloads/Freed-Wu/translate-shell/total)](https://github.com/Freed-Wu/translate-shell/releases)\n[![github/downloads/latest](https://shields.io/github/downloads/Freed-Wu/translate-shell/latest/total)](https://github.com/Freed-Wu/translate-shell/releases/latest)\n[![github/issues](https://shields.io/github/issues/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/issues)\n[![github/issues-closed](https://shields.io/github/issues-closed/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/issues?q=is%3Aissue+is%3Aclosed)\n[![github/issues-pr](https://shields.io/github/issues-pr/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/pulls)\n[![github/issues-pr-closed](https://shields.io/github/issues-pr-closed/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/pulls?q=is%3Apr+is%3Aclosed)\n[![github/discussions](https://shields.io/github/discussions/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/discussions)\n[![github/milestones](https://shields.io/github/milestones/all/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/milestones)\n[![github/forks](https://shields.io/github/forks/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/network/members)\n[![github/stars](https://shields.io/github/stars/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/stargazers)\n[![github/watchers](https://shields.io/github/watchers/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/watchers)\n[![github/contributors](https://shields.io/github/contributors/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/graphs/contributors)\n[![github/commit-activity](https://shields.io/github/commit-activity/w/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/graphs/commit-activity)\n[![github/last-commit](https://shields.io/github/last-commit/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/commits)\n[![github/release-date](https://shields.io/github/release-date/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/releases/latest)\n\n[![github/license](https://shields.io/github/license/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell/blob/main/LICENSE)\n[![github/languages](https://shields.io/github/languages/count/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell)\n[![github/languages/top](https://shields.io/github/languages/top/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell)\n[![github/directory-file-count](https://shields.io/github/directory-file-count/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell)\n[![github/code-size](https://shields.io/github/languages/code-size/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell)\n[![github/repo-size](https://shields.io/github/repo-size/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell)\n[![github/v](https://shields.io/github/v/release/Freed-Wu/translate-shell)](https://github.com/Freed-Wu/translate-shell)\n\n[![pypi/status](https://shields.io/pypi/status/translate-shell)](https://pypi.org/project/translate-shell/#description)\n[![pypi/v](https://shields.io/pypi/v/translate-shell)](https://pypi.org/project/translate-shell/#history)\n[![pypi/downloads](https://shields.io/pypi/dd/translate-shell)](https://pypi.org/project/translate-shell/#files)\n[![pypi/format](https://shields.io/pypi/format/translate-shell)](https://pypi.org/project/translate-shell/#files)\n[![pypi/implementation](https://shields.io/pypi/implementation/translate-shell)](https://pypi.org/project/translate-shell/#files)\n[![pypi/pyversions](https://shields.io/pypi/pyversions/translate-shell)](https://pypi.org/project/translate-shell/#files)\n\nTranslate text by:\n\n- online translators\n  - google\n  - bing\n  - youdaozhiyun\n  - haici\n- offline dictionaries\n  - stardict\n- LLM\n  - OpenAI\n  - llama: use your local model\n\nSupports:\n\n- CLI\n- GUI\n  - GNU/Linux\n  - Android\n  - macOS\n  - Windows\n- REPL\n- script:\n  - python\n  - shell\n  - vim: **DEPRECATION**: vim port will be replaced by language server\n- language server\n- CI/CD\n  - github action\n\n## Usage\n\n### UI\n\n#### CLI\n\n```sh\ntrans --translators=google,bing,haici,stardict crush\n```\n\n![CLI](https://user-images.githubusercontent.com/32936898/205699472-5349d422-54c9-47a3-afc0-53a17f0acaf8.jpg)\n\n#### REPL\n\n```console\n$ trans  # enter REPL\n\u003e en:ja  # change source language to english and target language to japanese\n\u003e :  # swap source and target languages\n\u003e =stardict  # use stardict to translate text\n\u003e !cat example/test.txt  # execute a shell command\nハッカー\n\u003e \u003cexample/test.txt   # translate a file\nhacker\n\u003e 画家  # translate text\npainter; artist\n\u003e !  # enter shell\n$ echo $SHELL  # execute a shell command\n/usr/bin/zsh\n$ exit  # exit shell\n\u003e\n```\n\n![REPL](https://user-images.githubusercontent.com/32936898/205617815-3a2ba6b4-2673-4233-907b-202ffd4a9e44.jpg)\n\n#### TUI\n\n##### Vim\n\n```vim\nTranslate --translators=google,bing Free as in Freedom\n```\n\n![Vim](https://user-images.githubusercontent.com/32936898/205475332-61c0a90e-b145-4af0-8658-c0cf45b87150.jpg)\n\n#### GUI\n\n##### GNU/Linux\n\n![GNU/Linux](https://user-images.githubusercontent.com/32936898/205699484-c6fdefd5-dca2-4263-aed4-e41d9d16fde6.jpg)\n\n##### Android\n\n![android-toast](https://user-images.githubusercontent.com/32936898/206078648-0db6480f-7e35-4252-9f33-9fb51e03e172.jpg)\n\n### Script\n\n#### Python\n\n```pycon\n\u003e\u003e\u003e from translate_shell.translate import translate\n\u003e\u003e\u003e translate(\"The Mythical Man-Month\", \"zh_TW\")\n... Translations(\n...     status=1,\n...     results=[\n...         Translation(\n...             translator=\"google\",\n...             sl=\"auto\",\n...             tl=\"zh_TW\",\n...             text=\"The Mythical Man-Month\",\n...             phonetic=\"\",\n...             paraphrase=\"神話般的人月\",\n...             explains={},\n...             details={},\n...             alternatives=[\"神話般的月\"]\n...         )\n...     ],\n...     text=\"The Mythical Man-Month\",\n...     to_lang=\"zh_TW\",\n...     from_lang=\"auto\",\n... )\n```\n\n#### Shell Script\n\n```console\n$ xsel -o | trans --format json | jq -r '\"《\\(.results[].paraphrase)》的英文是 \\(.text).\"'\n《大教堂和集市》的英文是 the cathedral and the bazaar.\n```\n\n#### Vim Script\n\n```vim\n:let g:text = 'Just for Fun'\n:let g:translation = json_decode(translate_shell#call('--format=json', g:text))\n:echo g:text 'is' g:translation.results[0].paraphrase 'in Chinese.'\nJust for Fun is 纯娱乐 in Chinese.\n```\n\n### Language server\n\n- [x] document hover: display translated results\n- [x] completions: complete translated words\n\n### CI/CD\n\n#### Github Action\n\nThis repo provides an action to translate `*.po` of a repository. See\n[inputs](https://github.com/Freed-Wu/translate-shell/blob/main/action.yml).\nFor example, you have a repository which contains translations of another\nproject's documents (upstream), you can write a github workflow to detect if\nupstream has update. If a new version exist, update the version and\ngenerate new\n[`.po`](https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files)s,\nthen translate the changed `.po`s and `git commit`.\n\nExamples:\n\n- [tmux-zh](https://github.com/Freed-Wu/tmux-zh/blob/main/.github/workflows/version.yml)\n\n```yaml\non:\n  schedule:\n    # Run this CI/CD at 0:00 on Friday\n    - cron: 0 0 * * 5\n  workflow_dispatch:\n\njobs:\n  translate:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - name: Generate new .po\n        id: version\n        run: |\n          # update version\n          # then use perl / sed / ... to replace the version string of your file\n          # then generate new .po\n          echo VERSION=XXX \u003e $GITHUB_OUTPUT\n      - name: Translate your *.po\n        uses: Freed-Wu/translate-shell@main\n      - name: Git commit\n        run: |\n          git add **.po\n          git config --global user.name 'Github Actions'\n          git config --global user.email '41898282+github-actions[bot]@users.noreply.github.com'\n          git commit -m \":bookmark: Dump version to $VERSION\"\n          git tag \"$VERSION\"\n          git remote set-url origin \"https://x-access-token:$GH_TOKEN@github.com/$GITHUB_REPOSITORY\"\n          git push\n          git push --tags\n        env:\n          VERSION: ${{steps.version.outputs.VERSION}}\n          GH_TOKEN: ${{secrets.GH_TOKEN}}\n```\n\nYou can use the following commands to get the new version:\n\n```bash\n# get a github repo's version:\ncurl https://api.github.com/repos/user/repo/releases/latest | jq -r .tag_name\n# get a gitlab repo's version\ncurl 'https://gitlab.com/api/v4/projects/41218592/repository/tags?per_page=1' |\njq -r '.[].name'\n```\n\nYou can use the following tools to generate the new `.po`s:\n\n- [sphinx-intl](https://sphinx-intl.readthedocs.io): Generate `.po` for any\n  project using sphinx to generate document.\n- [po4a](https://po4a.org): Generate `.po` for any project which use markdown,\n  `LaTeX`, man, ... to write document.\n\n## Similar Projects\n\nSee [comparison](https://translate-shell.readthedocs.io/en/latest/resources/translator.html).\n\n## Features\n\n- Translate with different translators at same time, like [translator](https://github.com/skywind3000/translator)\n- Translate clipboard contents automatically, like [ydcv](https://github.com/felixonmars/ydcv)\n- Speak the pronunciation of words\n- Support online translate engines\n- Support offline dictionaries\n- Many methods to use, from shell, python and vim\n- Magic text, like `en:` to change source language, `:zh_CN` to change target\n  language, `\u003cfile` to translate file, etc.\n- Allow customization by `config.py`\n- Good shell completions, especially for [zsh](https://github.com/zsh-users/zsh),\n  complete options and translation history\n- Manpage: `man trans`\n- Beautiful UI\n- Cross platforms\n- Rich API, can be easily called from shell and python\n- Good document\n- Unit test, keep code quality\n- CI/CD\n- clean code\n- Respect [PEP484](https://peps.python.org/pep-0484/)\n- Respect [PEP621](https://peps.python.org/pep-0621/)\n- Respect [XDG](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)\n\nThe last but not least: **it is a libre software**.\n\nSee [document](https://translate-shell.readthedocs.io) to know more.\n\nPS: PR is welcome! Please make code clean and keep test pass!\n\n\u003c!-- ex: nowrap\n--\u003e\n","funding_links":["https://patreon.com/user?u=83975719","https://user-images.githubusercontent.com/32936898/199681341-1c5cfa61-4411-4b67-b268-7cd87c5867bb.png","https://user-images.githubusercontent.com/32936898/199681363-1094a0be-85ca-49cf-a410-19b3d7965120.png","https://user-images.githubusercontent.com/32936898/199681368-c34c2be7-e0d8-43ea-8c2c-d3e865da6aeb.png"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreed-wu%2Ftranslate-shell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffreed-wu%2Ftranslate-shell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreed-wu%2Ftranslate-shell/lists"}