master a2b7b9574c22 cached
21 files
34.0 KB
8.5k tokens
14 symbols
1 requests
Download .txt
Repository: funkyremi/vscode-google-translate
Branch: master
Commit: a2b7b9574c22
Files: 21
Total size: 34.0 KB

Directory structure:
gitextract_x7f9err2/

├── .eslintrc.json
├── .gitattributes
├── .github/
│   └── workflows/
│       └── release.yml
├── .gitignore
├── .vscode/
│   ├── extensions.json
│   ├── launch.json
│   └── settings.json
├── .vscodeignore
├── CHANGELOG.md
├── LICENSE.txt
├── README.md
├── extension.js
├── jsconfig.json
├── languages.js
├── package.json
├── src/
│   ├── commands.js
│   ├── translate.js
│   └── utils.js
└── test/
    ├── runTest.js
    └── suite/
        ├── extension.test.js
        └── index.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .eslintrc.json
================================================
{
    "env": {
        "browser": false,
        "commonjs": true,
        "es6": true,
        "node": true
    },
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "sourceType": "module"
    },
    "rules": {
        "no-const-assign": "warn",
        "no-this-before-super": "warn",
        "no-undef": "warn",
        "no-unreachable": "warn",
        "no-unused-vars": "warn",
        "constructor-super": "warn",
        "valid-typeof": "warn"
    }
}

================================================
FILE: .gitattributes
================================================
# Set default behavior to automatically normalize line endings.
* text=auto



================================================
FILE: .github/workflows/release.yml
================================================
on:
  release:
    types: [published]
name: Deploy Extension
jobs:
  Publish:
    name: Publish
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@master
    - name: Install
      uses: actions/npm@master
      with:
        args: install --unsafe-perm
    - name: Publish
      uses: lannonbr/vsce-action@master
      env:
        VSCE_TOKEN: ${{ secrets.VSCE_TOKEN }}
      with:
        args: publish -p $VSCE_TOKEN


================================================
FILE: .gitignore
================================================
node_modules
.vscode-test/
server/out/*
*.vsix


================================================
FILE: .vscode/extensions.json
================================================
{
	// See http://go.microsoft.com/fwlink/?LinkId=827846
	// for the documentation about the extensions.json format
	"recommendations": [
		"dbaeumer.vscode-eslint"
	]
}

================================================
FILE: .vscode/launch.json
================================================
// A launch configuration that launches the extension inside a new window
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
	"version": "0.2.0",
    "configurations": [
        {
            "name": "Extension",
            "type": "extensionHost",
            "request": "launch",
            "runtimeExecutable": "${execPath}",
            "args": [
                "--extensionDevelopmentPath=${workspaceFolder}"
            ]
        },
        {
            "name": "Extension Tests",
            "type": "extensionHost",
            "request": "launch",
            "runtimeExecutable": "${execPath}",
            "args": [
                "--extensionDevelopmentPath=${workspaceFolder}",
                "--extensionTestsPath=${workspaceFolder}/test"
            ]
        }
    ]
}


================================================
FILE: .vscode/settings.json
================================================
// Place your settings in this file to overwrite default and user settings.
{
}

================================================
FILE: .vscodeignore
================================================
.vscode/**
.vscode-test/**
test/**
.gitignore
jsconfig.json
vsc-extension-quickstart.md
.eslintrc.json


================================================
FILE: CHANGELOG.md
================================================
# Change Log

## 1.5.0
- Refactor
- Bug fixed
- Dependencies bump
- Performance improvements
- Integration tests
- Remove hover translation feature and typescript code

## 1.4.13
- Update translation dependencies

## 1.4.12
- Put back the mandatory modules

## 1.4.11
- Exclude extra files from release

## 1.4.10
- Hotfix for 403 error

## 1.4.9
- Fix Hebrew language

## 1.4.8
- Show's translations when hovering over code and text

## 1.4.7
- Translate camel case support

## 1.4.6
- Improve default language settings
- Fix default shortcut

## 1.4.5
- Update translation library

## 1.4.4
- Add Uyghur language

## 1.4.3
- Add Chinese Traditional language

## 1.4.2
- Improve CI/CD

## 1.4.1
- Fix multi-line text translation

## 1.4.0
- Proxy support
- Fix HTML entity not decoded
- CI/CD with Github Actions

## 1.3.3
- Fix error messages not displayed

## 1.3.2
- Fix 'plugin stopped working' due to google unofficial api that stopped working

## 1.3.1
- Fix 'translation does nothing' random issue

## 1.3.0
- Add the translate of a line feature

## 1.2.0
- Prefered language setting

## 1.1.5
- Fix translation issue (#2)

## 1.1.4
- Change key biding to ALT+SHIFT+T to make it work with most of people
- Update readme

## 1.1.3
- Change key biding to CTRL+SHIFT+T or CMD+SHIFT+T

## 1.1.2
- Code improvements
- Better demo gif

## 1.1.1
- Add recently used languages

## 1.1.0
- Multiselect support
- Update readme
- MIT License
- Gif example
- Badges
- Logo

## 1.0.2
- Minor improvements

## 1.0.1
- Minor improvements

## 1.0.0
- Initial release

================================================
FILE: LICENSE.txt
================================================
The MIT License (MIT)

Copyright (c) 2016 HookyQR

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

================================================
FILE: README.md
================================================
# Vscode Google Translate

Quickly translate text right in your code 🚀

![Demo](demo.gif)

## Usage

### Translate selected text

1. Select some text to translate
1. Press `ALT+SHIFT+T`
1. Select the output languages you want and enjoy 👍

### Translate a line under cursor

This feature inserts a newline under the current one with translation

1. Set cursor/cursors on line(s) to translate
1. Select menu 'Translate line(s) under the cursor'
1. Select the output languages you want and enjoy

## Preferred language settings

Want to quickly translate into a specific language?
Run Command 'Set Preferred Language' or Set it in VSCode extension settings



## Proxy Support

You can use a proxy to translate text with the following settings:

```js
"vscodeGoogleTranslate.host": "120.0.0.1"       // Proxy disabled if empty
"vscodeGoogleTranslate.port": "8080"            // Proxy port
"vscodeGoogleTranslate.username": "admin"       // Proxy auth disabled if empty
"vscodeGoogleTranslate.password": "password"    // Proxy password
```

## Pull request

Pull request are welcome. Fork the project, clone it, install dependencies `npm i` and start coding :-).

Many thanks to the people who participate for making it awesome!

## Show your support

**Give five stars 🤩**

If you like it, [rate it](https://marketplace.visualstudio.com/items?itemName=funkyremi.vscode-google-translate&ssr=false#review-details)


================================================
FILE: extension.js
================================================
const { initializeCommands } = require('./src/commands');

function activate(context) {
  initializeCommands(context);
}

exports.activate = activate;


================================================
FILE: jsconfig.json
================================================
{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "checkJs": false,  /* Typecheck .js files. */
        "lib": [
            "es6"
        ]
    },
    "exclude": [
        "node_modules"
    ]
}

================================================
FILE: languages.js
================================================
const languages = [
	{
		name: 'Afrikaans',
		value: 'af',
	}, {
		name: 'Albanian',
		value: 'sq',
	}, {
		name: 'Amharic',
		value: 'am',
	}, {
		name: 'Arabic',
		value: 'ar',
	}, {
		name: 'Armenian',
		value: 'hy',
	}, {
		name: 'Azeerbaijani',
		value: 'az',
	}, {
		name: 'Basque',
		value: 'eu',
	}, {
		name: 'Belarusian',
		value: 'be',
	}, {
		name: 'Bengali',
		value: 'bn',
	}, {
		name: 'Bosnian',
		value: 'bs',
	}, {
		name: 'Bulgarian',
		value: 'bg',
	}, {
		name: 'Catalan',
		value: 'ca',
	}, {
		name: 'Cebuano',
		value: 'ceb',
	}, {
		name: 'Chinese (Simplified)',
		value: 'zh-CN',
	}, {
		name: 'Chinese (Traditional)',
		value: 'zh-TW',
	}, {
		name: 'Corsican',
		value: 'co',
	}, {
		name: 'Croatian',
		value: 'hr',
	}, {
		name: 'Czech',
		value: 'cs',
	}, {
		name: 'Danish',
		value: 'da',
	}, {
		name: 'Dutch',
		value: 'nl',
	}, {
		name: 'English',
		value: 'en',
	}, {
		name: 'Esperanto',
		value: 'eo',
	}, {
		name: 'Estonian',
		value: 'et',
	}, {
		name: 'Finnish',
		value: 'fi',
	}, {
		name: 'French',
		value: 'fr',
	}, {
		name: 'Frisian',
		value: 'fy',
	}, {
		name: 'Galician',
		value: 'gl',
	}, {
		name: 'Georgian',
		value: 'ka',
	}, {
		name: 'German',
		value: 'de',
	}, {
		name: 'Greek',
		value: 'el',
	}, {
		name: 'Gujarati',
		value: 'gu',
	}, {
		name: 'Haitian Creole',
		value: 'ht',
	}, {
		name: 'Hausa',
		value: 'ha',
	}, {
		name: 'Hawaiian',
		value: 'haw',
	}, {
		name: 'Hebrew',
		value: 'iw',
	}, {
		name: 'Hindi',
		value: 'hi',
	}, {
		name: 'Hmong',
		value: 'hmn',
	}, {
		name: 'Hungarian',
		value: 'hu',
	}, {
		name: 'Icelandic',
		value: 'is',
	}, {
		name: 'Igbo',
		value: 'ig',
	}, {
		name: 'Indonesian',
		value: 'id',
	}, {
		name: 'Irish',
		value: 'ga',
	}, {
		name: 'Italian',
		value: 'it',
	}, {
		name: 'Japanese',
		value: 'ja',
	}, {
		name: 'Javanese',
		value: 'jw',
	}, {
		name: 'Kannada',
		value: 'kn',
	}, {
		name: 'Kazakh',
		value: 'kk',
	}, {
		name: 'Khmer',
		value: 'km',
	}, {
		name: 'Korean',
		value: 'ko',
	}, {
		name: 'Kurdish',
		value: 'ku',
	}, {
		name: 'Kyrgyz',
		value: 'ky',
	}, {
		name: 'Lao',
		value: 'lo',
	}, {
		name: 'Latin',
		value: 'la',
	}, {
		name: 'Latvian',
		value: 'lv',
	}, {
		name: 'Lithuanian',
		value: 'lt',
	}, {
		name: 'Luxembourgish',
		value: 'lb',
	}, {
		name: 'Macedonian',
		value: 'mk',
	}, {
		name: 'Malagasy',
		value: 'mg',
	}, {
		name: 'Malay',
		value: 'ms',
	}, {
		name: 'Malayalam',
		value: 'ml',
	}, {
		name: 'Maltese',
		value: 'mt',
	}, {
		name: 'Maori',
		value: 'mi',
	}, {
		name: 'Marathi',
		value: 'mr',
	}, {
		name: 'Mongolian',
		value: 'mn',
	}, {
		name: 'Myanmar',
		value: 'my',
	}, {
		name: 'Nepali',
		value: 'ne',
	}, {
		name: 'Norwegian',
		value: 'no',
	}, {
		name: 'Nyanja',
		value: 'ny',
	}, {
		name: 'Pashto',
		value: 'ps',
	}, {
		name: 'Persian',
		value: 'fa',
	}, {
		name: 'Polish',
		value: 'pl',
	}, {
		name: 'Portuguese',
		value: 'pt',
	}, {
		name: 'Punjabi',
		value: 'pa',
	}, {
		name: 'Romanian',
		value: 'ro',
	}, {
		name: 'Russian',
		value: 'ru',
	}, {
		name: 'Samoan',
		value: 'sm',
	}, {
		name: 'Scots Gaelic',
		value: 'gd',
	}, {
		name: 'Serbian',
		value: 'sr',
	}, {
		name: 'Sesotho',
		value: 'st',
	}, {
		name: 'Shona',
		value: 'sn',
	}, {
		name: 'Sindhi',
		value: 'sd',
	}, {
		name: 'Sinhala',
		value: 'si',
	}, {
		name: 'Slovak',
		value: 'sk',
	}, {
		name: 'Slovenian',
		value: 'sl',
	}, {
		name: 'Somali',
		value: 'so',
	}, {
		name: 'Spanish',
		value: 'es',
	}, {
		name: 'Sundanese',
		value: 'su',
	}, {
		name: 'Swahili',
		value: 'sw',
	}, {
		name: 'Swedish',
		value: 'sv',
	}, {
		name: 'Tagalog',
		value: 'tl',
	}, {
		name: 'Tajik',
		value: 'tg',
	}, {
		name: 'Tamil',
		value: 'ta',
	}, {
		name: 'Telugu',
		value: 'te',
	}, {
		name: 'Thai',
		value: 'th',
	}, {
		name: 'Turkish',
		value: 'tr',
	}, {
		name: 'Ukrainian',
		value: 'uk',
	}, {
		name: 'Urdu',
		value: 'ur',
	}, {
		name: 'Uyghur',
		value: 'ug',
	}, {
		name: 'Uzbek',
		value: 'uz',
	}, {
		name: 'Vietnamese',
		value: 'vi',
	}, {
		name: 'Welsh',
		value: 'cy',
	}, {
		name: 'Xhosa',
		value: 'xh',
	}, {
		name: 'Yiddish',
		value: 'yi',
	}, {
		name: 'Yoruba',
		value: 'yo',
	}, {
		name: 'Zulu',
		value: 'zu',
	}
];

module.exports = languages;


================================================
FILE: package.json
================================================
{
    "name": "vscode-google-translate",
    "displayName": "Vscode Google Translate",
    "description": "Translate text right in your code",
    "publisher": "funkyremi",
    "version": "1.5.0",
    "license": "MIT",
    "icon": "icon.png",
    "repository": {
        "type": "git",
        "url": "https://github.com/funkyremi/vscode-google-translate.git"
    },
    "engines": {
        "vscode": "^1.29.0"
    },
    "categories": [
        "Formatters"
    ],
    "activationEvents": [
        "onCommand:extension.translateText",
        "onCommand:extension.translateTextPreferred",
        "onCommand:extension.translateLinesUnderCursor",
        "onCommand:extension.setPreferredLanguage",
        "onCommand:extension.translateLinesUnderCursorPreferred"
    ],
    "main": "./extension",
    "contributes": {
        "commands": [
            {
                "command": "extension.translateText",
                "title": "Translate selection(s)"
            },
            {
                "command": "extension.translateTextPreferred",
                "title": "Translate selection(s) to preferred language"
            },
            {
                "command": "extension.translateLinesUnderCursor",
                "title": "Translate line(s) under the cursor"
            },
            {
                "command": "extension.setPreferredLanguage",
                "title": "Set preferred target language"
            },
            {
                "command": "extension.translateLinesUnderCursorPreferred",
                "title": "Translate line(s) under the cursor to preferred language"
            }
        ],
        "configuration": {
            "title": "Vscode Google Translate",
            "type": "object",
            "properties": {
                "vscodeGoogleTranslate.preferredLanguage": {
                    "type": "string",
                    "enum": [
                        "Afrikaans",
                        "Albanian",
                        "Amharic",
                        "Arabic",
                        "Armenian",
                        "Azeerbaijani",
                        "Basque",
                        "Belarusian",
                        "Bengali",
                        "Bosnian",
                        "Bulgarian",
                        "Catalan",
                        "Cebuano",
                        "Chinese (Simplified)",
                        "Chinese (Traditional)",
                        "Corsican",
                        "Croatian",
                        "Czech",
                        "Danish",
                        "Dutch",
                        "English",
                        "Esperanto",
                        "Estonian",
                        "Finnish",
                        "French",
                        "Frisian",
                        "Galician",
                        "Georgian",
                        "German",
                        "Greek",
                        "Gujarati",
                        "Haitian Creole",
                        "Hausa",
                        "Hawaiian",
                        "Hebrew",
                        "Hindi",
                        "Hmong",
                        "Hungarian",
                        "Icelandic",
                        "Igbo",
                        "Indonesian",
                        "Irish",
                        "Italian",
                        "Japanese",
                        "Javanese",
                        "Kannada",
                        "Kazakh",
                        "Khmer",
                        "Korean",
                        "Kurdish",
                        "Kyrgyz",
                        "Lao",
                        "Latin",
                        "Latvian",
                        "Lithuanian",
                        "Luxembourgish",
                        "Macedonian",
                        "Malagasy",
                        "Malay",
                        "Malayalam",
                        "Maltese",
                        "Maori",
                        "Marathi",
                        "Mongolian",
                        "Myanmar",
                        "Nepali",
                        "Norwegian",
                        "Nyanja",
                        "Pashto",
                        "Persian",
                        "Polish",
                        "Portuguese",
                        "Punjabi",
                        "Romanian",
                        "Russian",
                        "Samoan",
                        "Scots Gaelic",
                        "Serbian",
                        "Sesotho",
                        "Shona",
                        "Sindhi",
                        "Sinhala",
                        "Slovak",
                        "Slovenian",
                        "Somali",
                        "Spanish",
                        "Sundanese",
                        "Swahili",
                        "Swedish",
                        "Tagalog",
                        "Tajik",
                        "Tamil",
                        "Telugu",
                        "Thai",
                        "Turkish",
                        "Ukrainian",
                        "Urdu",
                        "Uyghur",
                        "Uzbek",
                        "Vietnamese",
                        "Welsh",
                        "Xhosa",
                        "Yiddish",
                        "Yoruba",
                        "Zulu"
                    ],
                    "description": "The preferred target language"
                },
                "vscodeGoogleTranslate.proxyHost": {
                    "type": "string",
                    "description": "The proxy host (set it to enable proxy) (Optional)"
                },
                "vscodeGoogleTranslate.proxyPort": {
                    "type": "string",
                    "description": "The proxy port (Optional)"
                },
                "vscodeGoogleTranslate.proxyUsername": {
                    "type": "string",
                    "description": "The proxy username (Optional)"
                },
                "vscodeGoogleTranslate.proxyPassword": {
                    "type": "string",
                    "description": "The proxy password (Optional)"
                }
            }
        },
        "keybindings": [
            {
                "key": "alt+shift+t",
                "when": "editorTextFocus",
                "command": "extension.translateText"
            }
        ]
    },
    "scripts": {
        "test": "node ./test/runTest.js"
    },
    "devDependencies": {
        "@types/mocha": "^10.0.6",
        "@types/node": "^20.11.24",
        "@vscode/test-electron": "^2.5.2",
        "eslint": "^8.56.0",
        "glob": "^11.0.3",
        "mocha": "^11.7.2"
    },
    "dependencies": {
        "@types/vscode": "^1.84.0",
        "@vitalets/google-translate-api": "^9.2.1",
        "camelcase": "^8.0.0",
        "he": "^1.2.0",
        "http-proxy-agent": "^7.0.2",
        "humanize-string": "^3.0.0",
        "typescript": "^5.3.3"
    }
}


================================================
FILE: src/commands.js
================================================
const vscode = require('vscode');
const he = require("he");
const languages = require('../languages.js');
const {
    recentlyUsed,
    updateLanguageList,
    getSelectedText,
    getSelectedLineText,
    getPreferredLanguage,
    setPreferredLanguage,
} = require('./utils');
const { getTranslationPromise } = require('./translate');

function getTranslationsPromiseArray(selections, document, selectedLanguage) {
    return selections.map((selection) => {
      const selectedText = getSelectedText(document, selection);
      return getTranslationPromise(selectedText, selectedLanguage, selection);
    });
  }
  
  function getTranslationsPromiseArrayLine(
    selections,
    document,
    selectedLanguage
  ) {
    return selections.map((selection) => {
      const selectedLineText = getSelectedLineText(document, selection);
      return getTranslationPromise(selectedLineText, selectedLanguage, selection);
    });
  }

function initializeCommands(context) {
    const translateText = vscode.commands.registerCommand(
        "extension.translateText",
        function () {
          const editor = vscode.window.activeTextEditor;
          const { document, selections } = editor;
    
          const quickPickData = recentlyUsed
            .map((r) => ({
              label: r,
              description: "(recently used)",
            }))
            .concat(languages.map((r) => ({ label: r.name })));
    
          vscode.window
            .showQuickPick(quickPickData)
            .then((selectedLanguage) => {
              if (!selectedLanguage) return;
              updateLanguageList(selectedLanguage.label);
              const translationsPromiseArray = getTranslationsPromiseArray(
                selections,
                document,
                languages.find((r) => r.name === selectedLanguage.label).value
              );
              Promise.all(translationsPromiseArray)
                .then(function (results) {
                  editor.edit((builder) => {
                    results.forEach((r) => {
                      if (!!r.translation) {
                        builder.replace(r.selection, he.decode(r.translation));
                      }
                    });
                  });
                })
                .catch((e) => vscode.window.showErrorMessage(e.message));
            })
            .catch((err) => {
              vscode.window.showErrorMessage(err.message);
            });
        }
      );
      context.subscriptions.push(translateText);
    
      const setPreferredLanguageFnc = vscode.commands.registerCommand(
        "extension.setPreferredLanguage",
        setPreferredLanguage
      );
      context.subscriptions.push(setPreferredLanguageFnc);
    
      const translateTextPreferred = vscode.commands.registerCommand(
        "extension.translateTextPreferred",
        async function () {
          const editor = vscode.window.activeTextEditor;
          const { document, selections } = editor;
    
          // vscodeTranslate.preferredLanguage
          const preferredLanguage = await getPreferredLanguage();
          const locale = languages.find(
            (element) => element.name === preferredLanguage
          ).value;
          if (!locale) {
            return;
          }
    
          const translationsPromiseArray = getTranslationsPromiseArray(
            selections,
            document,
            locale
          );
          Promise.all(translationsPromiseArray)
            .then(function (results) {
              editor.edit((builder) => {
                results.forEach((r) => {
                  if (!!r.translation) {
                    builder.replace(r.selection, he.decode(r.translation));
                  }
                });
              });
            })
            .catch((e) => vscode.window.showErrorMessage(e.message));
        }
      );
      context.subscriptions.push(translateTextPreferred);
    
      const translateLinesUnderCursor = vscode.commands.registerCommand(
        "extension.translateLinesUnderCursor",
        function translateLinesUnderCursorcallback() {
          const editor = vscode.window.activeTextEditor;
          const { document, selections } = editor;
    
          const quickPickData = recentlyUsed
            .map((r) => ({
              label: r.name,
              description: "(recently used)",
            }))
            .concat(languages.map((r) => ({ label: r.name })));
    
          vscode.window
            .showQuickPick(quickPickData)
            .then((selectedLanguage) => {
              if (!selectedLanguage) return;
              updateLanguageList(selectedLanguage.label);
              const translationsPromiseArray = getTranslationsPromiseArrayLine(
                selections,
                document,
                languages.find((r) => r.name === selectedLanguage.label).value
              );
              Promise.all(translationsPromiseArray)
                .then(function (results) {
                  editor.edit((builder) => {
                    results.forEach((r) => {
                      if (!!r.translation) {
                        const ffix = ["", "\n"];
                        if (
                          editor.document.lineCount - 1 ===
                          r.selection.start.line
                        )
                          [ffix[0], ffix[1]] = [ffix[1], ffix[0]];
                        const p = new vscode.Position(r.selection.start.line + 1);
                        builder.insert(p, `${ffix[0]}${r.translation}${ffix[1]}`);
                      }
                    });
                  });
                })
                .catch((e) => vscode.window.showErrorMessage(e.message));
            })
            .catch((err) => {
              vscode.window.showErrorMessage(err.message);
            });
        }
      );
    
      context.subscriptions.push(translateLinesUnderCursor);
    
      const translateLinesUnderCursorPreferred = vscode.commands.registerCommand(
        "extension.translateLinesUnderCursorPreferred",
        async function translateLinesUnderCursorPreferredcallback() {
          const editor = vscode.window.activeTextEditor;
          const { document, selections } = editor;
          const preferredLanguage = await getPreferredLanguage();
          const locale = languages.find(
            (element) => element.name === preferredLanguage
          ).value;
          if (!locale) {
            vscode.window.showWarningMessage(
              "Prefered language is requeried for this feature! Please set this in the settings."
            );
            return;
          }
    
          const translationsPromiseArray = getTranslationsPromiseArrayLine(
            selections,
            document,
            locale
          );
    
          Promise.all(translationsPromiseArray)
            .then(function (results) {
              editor.edit((builder) => {
                results.forEach((r) => {
                  if (!!r.translation) {
                    const ffix = ["", "\n"];
                    if (editor.document.lineCount - 1 === r.selection.start.line)
                      [ffix[0], ffix[1]] = [ffix[1], ffix[0]];
                    const p = new vscode.Position(r.selection.start.line + 1);
                    builder.insert(p, `${ffix[0]}${r.translation}${ffix[1]}`);
                  }
                });
              });
            })
            .catch((e) => vscode.window.showErrorMessage(e.message));
        }
      );
      context.subscriptions.push(translateLinesUnderCursorPreferred);
}

module.exports = { initializeCommands };


================================================
FILE: src/translate.js
================================================
const { translate: gti } = require("@vitalets/google-translate-api");
const { HttpProxyAgent } = require('http-proxy-agent');
const humanizeString = require("humanize-string");
const camelcase = require("camelcase");
const { getProxyConfig } = require("./utils");

async function translate(text, options) {
    const translateOptions = {
      to: options.to,
      fetchOptions: {}
    };
  
    if (options && options.proxy) {
      const proxyUrl = `http://${options.proxy.auth ? `${options.proxy.auth.username}:${options.proxy.auth.password}@` : ''}${options.proxy.host}:${options.proxy.port}`;
      translateOptions.fetchOptions.agent = new HttpProxyAgent(proxyUrl);
    }
  
    const { text: translatedText } = await gti(text, translateOptions);
    // The old code expected an object with a 'data' array. We'll mimic that.
    return { data: [translatedText] };
  }

  async function getTranslationPromise(selectedText, selectedLanguage, selection) {
    const { host, port, username, password } = getProxyConfig();
    const translationConfiguration = {
      to: selectedLanguage,
    };
    if (!!host) {
      translationConfiguration.proxy = {
        host,
        port: Number(port),
      };
      if (!!username) {
        translationConfiguration.proxy.auth = {
          username,
          password,
        };
      }
    }
  
    try {
      let res = await translate(selectedText, translationConfiguration);
  
      if (!!res && !!res.data) {
        // If google rejects the string it will return the same string as input
        // We can try to split the string into parts, then translate again. Then return it to a
        // camel style casing
        if (res.data[0] === selectedText) {
          const humanizedRes = await translate(humanizeString(selectedText), translationConfiguration);
          if (!!humanizedRes && !!humanizedRes.data) {
            return {
              selection,
              translation: camelcase(humanizedRes.data[0]),
            };
          } else {
            throw new Error("Google Translation API issue on fallback");
          }
        } else {
          return {
            selection,
            translation: res.data[0],
          };
        }
      } else {
        throw new Error("Google Translation API issue");
      }
    } catch (e) {
      // The original function returned a Promise.reject, so we'll throw an error
      // which will be caught by the caller's .catch block.
      throw new Error("Google Translation API issue: " + e.message);
    }
  }

  module.exports = {
      getTranslationPromise
  }


================================================
FILE: src/utils.js
================================================
const vscode = require('vscode');
const languages = require('../languages.js');

/**
 * The list of recently used languages
 *
 * @type {Array.<string>}
 */
const recentlyUsed = [];

/**
 * Updates languages lists for the convenience of users
 *
 * @param {string} selectedLanguage The language code to update
 * @returns {undefined}
 */
function updateLanguageList(selectedLanguage) {
  const index = recentlyUsed.findIndex((r) => r === selectedLanguage);
  if (index !== -1) {
    // Remove the recently used language from the list
    recentlyUsed.splice(index, 1);
  }
  // Add the language in recently used languages
  recentlyUsed.splice(0, 0, selectedLanguage);
}

/**
 * Extracts a text from the active document selection
 *
 * @param {vscode.TextDocument} document The current document
 * @param {vscode.Selection} selection The current selection
 * @returns {string} A text
 */
function getSelectedText(document, selection) {
  const charRange = new vscode.Range(
    selection.start.line,
    selection.start.character,
    selection.end.line,
    selection.end.character
  );
  return document.getText(charRange);
}

/**
 * Gets a text of the first line from active selection
 *
 * @param {vscode.TextDocument} document The current document
 * @param {vscode.Selection} selection The current selection
 * @returns {string}
 */
function getSelectedLineText(document, selection) {
  return document.getText(
    document.lineAt(selection.start.line).rangeIncludingLineBreak
  );
}

/**
 * Returns user settings Preferred language.
 * If user hasn't set preferred lang. Prompt to set.
 */
function getPreferredLanguage() {
  return (
    vscode.workspace
      .getConfiguration("vscodeGoogleTranslate")
      .get("preferredLanguage") || setPreferredLanguage()
  );
}

async function setPreferredLanguage() {
  const quickPickData = recentlyUsed
    .map((r) => ({
      label: r,
      description: "(recently used)",
    }))
    .concat(languages.map((r) => ({ label: r.name })));

  const selectedLanguage = await vscode.window.showQuickPick(quickPickData);
  if (!selectedLanguage) {
    return;
  }
  vscode.workspace
    .getConfiguration()
    .update(
      "vscodeGoogleTranslate.preferredLanguage",
      selectedLanguage.label,
      vscode.ConfigurationTarget.Global
    );
  return selectedLanguage.label;
}

/**
 * Returns user settings proxy config
 *
 * @returns {string}
 */
function getProxyConfig() {
  const config = vscode.workspace.getConfiguration("vscodeGoogleTranslate");
  return {
    host: config.get("proxyHost"),
    port: config.get("proxyPort"),
    username: config.get("proxyUsername"),
    password: config.get("proxyPassword"),
  };
}

module.exports = {
    recentlyUsed,
    updateLanguageList,
    getSelectedText,
    getSelectedLineText,
    getPreferredLanguage,
    setPreferredLanguage,
    getProxyConfig
}


================================================
FILE: test/runTest.js
================================================
const path = require('path');
const { runTests } = require('@vscode/test-electron');

async function main() {
  try {
    // The folder containing the Extension Manifest package.json
    // Passed to `--extensionDevelopmentPath`
    const extensionDevelopmentPath = path.resolve(__dirname, '../');

    // The path to the extension test script
    // Passed to --extensionTestsPath
    const extensionTestsPath = path.resolve(__dirname, './suite/index');

    // Download VS Code, unzip it and run the integration test
    await runTests({ extensionDevelopmentPath, extensionTestsPath });
  } catch (err) {
    console.error('Failed to run tests');
    process.exit(1);
  }
}

main();


================================================
FILE: test/suite/extension.test.js
================================================
/* global suite, test, setup */
const assert = require('assert');
const vscode = require('vscode');

suite("Extension Command Tests", function() {
    setup(async () => {
        // Set a preferred language to avoid the quick pick menu
        await vscode.workspace.getConfiguration('vscodeGoogleTranslate').update('preferredLanguage', 'French', vscode.ConfigurationTarget.Global);
    });

    test("Should translate selected text", async () => {
        const document = await vscode.workspace.openTextDocument({ content: 'Hello World' });
        const editor = await vscode.window.showTextDocument(document);
        
        const originalText = 'Hello World';
        editor.selection = new vscode.Selection(new vscode.Position(0, 0), new vscode.Position(0, originalText.length));

        // Give a moment for the extension to activate if it hasn't already
        await new Promise(resolve => setTimeout(resolve, 1000));

        await vscode.commands.executeCommand('extension.translateTextPreferred');

        // Add a delay to allow for the translation and edit to occur
        await new Promise(resolve => setTimeout(resolve, 2000));

        const newText = editor.document.getText();

        // We don't know the exact translation, but it should not be the original text.
        assert.notStrictEqual(newText, originalText);
        // A very basic check to see if it could be the French translation
        assert.ok(newText.toLowerCase().includes('bonjour'));
    }).timeout(5000); // Increase timeout to allow for API calls
});


================================================
FILE: test/suite/index.js
================================================
const path = require('path');
const Mocha = require('mocha');
const { glob } = require('glob');

function run() {
    // Create the mocha test
    const mocha = new Mocha({
        ui: 'tdd',
        color: true
    });

    const testsRoot = path.resolve(__dirname, '.');

    return new Promise((c, e) => {
        glob('**/**.test.js', { cwd: testsRoot })
            .then(files => {
                // Add files to the test suite
                files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));

                try {
                    // Run the mocha test
                    mocha.run(failures => {
                        if (failures > 0) {
                            e(new Error(`${failures} tests failed.`));
                        } else {
                            c();
                        }
                    });
                } catch (err) {
                    console.error(err);
                    e(err);
                }
            })
            .catch(err => {
                return e(err);
            });
    });
}

module.exports = {
    run
};
Download .txt
gitextract_x7f9err2/

├── .eslintrc.json
├── .gitattributes
├── .github/
│   └── workflows/
│       └── release.yml
├── .gitignore
├── .vscode/
│   ├── extensions.json
│   ├── launch.json
│   └── settings.json
├── .vscodeignore
├── CHANGELOG.md
├── LICENSE.txt
├── README.md
├── extension.js
├── jsconfig.json
├── languages.js
├── package.json
├── src/
│   ├── commands.js
│   ├── translate.js
│   └── utils.js
└── test/
    ├── runTest.js
    └── suite/
        ├── extension.test.js
        └── index.js
Download .txt
SYMBOL INDEX (14 symbols across 6 files)

FILE: extension.js
  function activate (line 3) | function activate(context) {

FILE: src/commands.js
  function getTranslationsPromiseArray (line 14) | function getTranslationsPromiseArray(selections, document, selectedLangu...
  function getTranslationsPromiseArrayLine (line 21) | function getTranslationsPromiseArrayLine(
  function initializeCommands (line 32) | function initializeCommands(context) {

FILE: src/translate.js
  function translate (line 7) | async function translate(text, options) {
  function getTranslationPromise (line 23) | async function getTranslationPromise(selectedText, selectedLanguage, sel...

FILE: src/utils.js
  function updateLanguageList (line 17) | function updateLanguageList(selectedLanguage) {
  function getSelectedText (line 34) | function getSelectedText(document, selection) {
  function getSelectedLineText (line 51) | function getSelectedLineText(document, selection) {
  function getPreferredLanguage (line 61) | function getPreferredLanguage() {
  function setPreferredLanguage (line 69) | async function setPreferredLanguage() {
  function getProxyConfig (line 96) | function getProxyConfig() {

FILE: test/runTest.js
  function main (line 4) | async function main() {

FILE: test/suite/index.js
  function run (line 5) | function run() {
Condensed preview — 21 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (38K chars).
[
  {
    "path": ".eslintrc.json",
    "chars": 499,
    "preview": "{\n    \"env\": {\n        \"browser\": false,\n        \"commonjs\": true,\n        \"es6\": true,\n        \"node\": true\n    },\n    "
  },
  {
    "path": ".gitattributes",
    "chars": 77,
    "preview": "# Set default behavior to automatically normalize line endings.\n* text=auto\n\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 435,
    "preview": "on:\n  release:\n    types: [published]\nname: Deploy Extension\njobs:\n  Publish:\n    name: Publish\n    runs-on: ubuntu-late"
  },
  {
    "path": ".gitignore",
    "chars": 47,
    "preview": "node_modules\n.vscode-test/\nserver/out/*\n*.vsix\n"
  },
  {
    "path": ".vscode/extensions.json",
    "chars": 168,
    "preview": "{\n\t// See http://go.microsoft.com/fwlink/?LinkId=827846\n\t// for the documentation about the extensions.json format\n\t\"rec"
  },
  {
    "path": ".vscode/launch.json",
    "chars": 931,
    "preview": "// A launch configuration that launches the extension inside a new window\n// Use IntelliSense to learn about possible at"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 79,
    "preview": "// Place your settings in this file to overwrite default and user settings.\n{\n}"
  },
  {
    "path": ".vscodeignore",
    "chars": 103,
    "preview": ".vscode/**\n.vscode-test/**\ntest/**\n.gitignore\njsconfig.json\nvsc-extension-quickstart.md\n.eslintrc.json\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 1558,
    "preview": "# Change Log\n\n## 1.5.0\n- Refactor\n- Bug fixed\n- Dependencies bump\n- Performance improvements\n- Integration tests\n- Remov"
  },
  {
    "path": "LICENSE.txt",
    "chars": 1073,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2016 HookyQR\n\nPermission is hereby granted, free of charge, to any person obtaining"
  },
  {
    "path": "README.md",
    "chars": 1409,
    "preview": "# Vscode Google Translate\n\nQuickly translate text right in your code 🚀\n\n![Demo](demo.gif)\n\n## Usage\n\n### Translate selec"
  },
  {
    "path": "extension.js",
    "chars": 151,
    "preview": "const { initializeCommands } = require('./src/commands');\n\nfunction activate(context) {\n  initializeCommands(context);\n}"
  },
  {
    "path": "jsconfig.json",
    "chars": 235,
    "preview": "{\n    \"compilerOptions\": {\n        \"module\": \"commonjs\",\n        \"target\": \"es6\",\n        \"checkJs\": false,  /* Typechec"
  },
  {
    "path": "languages.js",
    "chars": 4294,
    "preview": "const languages = [\n\t{\n\t\tname: 'Afrikaans',\n\t\tvalue: 'af',\n\t}, {\n\t\tname: 'Albanian',\n\t\tvalue: 'sq',\n\t}, {\n\t\tname: 'Amhar"
  },
  {
    "path": "package.json",
    "chars": 7254,
    "preview": "{\n    \"name\": \"vscode-google-translate\",\n    \"displayName\": \"Vscode Google Translate\",\n    \"description\": \"Translate tex"
  },
  {
    "path": "src/commands.js",
    "chars": 7681,
    "preview": "const vscode = require('vscode');\nconst he = require(\"he\");\nconst languages = require('../languages.js');\nconst {\n    re"
  },
  {
    "path": "src/translate.js",
    "chars": 2595,
    "preview": "const { translate: gti } = require(\"@vitalets/google-translate-api\");\nconst { HttpProxyAgent } = require('http-proxy-age"
  },
  {
    "path": "src/utils.js",
    "chars": 2862,
    "preview": "const vscode = require('vscode');\nconst languages = require('../languages.js');\n\n/**\n * The list of recently used langua"
  },
  {
    "path": "test/runTest.js",
    "chars": 685,
    "preview": "const path = require('path');\nconst { runTests } = require('@vscode/test-electron');\n\nasync function main() {\n  try {\n  "
  },
  {
    "path": "test/suite/extension.test.js",
    "chars": 1550,
    "preview": "/* global suite, test, setup */\nconst assert = require('assert');\nconst vscode = require('vscode');\n\nsuite(\"Extension Co"
  },
  {
    "path": "test/suite/index.js",
    "chars": 1103,
    "preview": "const path = require('path');\nconst Mocha = require('mocha');\nconst { glob } = require('glob');\n\nfunction run() {\n    //"
  }
]

About this extraction

This page contains the full source code of the funkyremi/vscode-google-translate GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 21 files (34.0 KB), approximately 8.5k tokens, and a symbol index with 14 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!