github github
stars 287
issues 6
subscribers 1
forks 2



2 months ago


tests versions

With pantran.nvim, you can use your favorite machine translation engines without having to leave your favorite editor. It makes use of Neovim's api-floatwin to implement an asynchronous, interactive machine translation interface, similar to how most of the various machine translation web front-ends work. In addition to that, other (non-interactive) modes are also supported and, if you try hard enough, pantran.nvim can also be used as an API.

Pantran.nvim demonstration

Warning: This is beta quality software. It should run stable for the most part, but don't be too surprised if you find a few bugs here and there. Use at your own risk!


You need at least Neovim v0.6.1 and curl v7.76.0 to be able to use this plugin. You can install it using your favorite plugin manager.

With vim-plug:

Plug "potamides/pantran.nvim"

With dein:

call dein#add("potamides/pantran.nvim")

With packer.nvim:

use {


Run the command :Pantran to open an interactive translation window and start typing to get an understanding of how things work. Type g? in normal mode or i_CTRL-/ in insert mode to open a help buffer with available keybindings. :Pantran also supports command ranges to initialize the translation window. Further, some optional flags for configuration of the translation process are available, consult the documentation for more details. If you plan to translate frequently, the command can also be mapped to the following recommended keybindings:

local opts = {noremap = true, silent = true, expr = true}
vim.keymap.set("n", "<leader>tr", pantran.motion_translate, opts)
vim.keymap.set("n", "<leader>trr", function() return pantran.motion_translate() .. "_" end, opts)
vim.keymap.set("x", "<leader>tr", pantran.motion_translate, opts)
local opts = {noremap = true, silent = true, expr = true}
vim.api.nvim_set_keymap("n", "<leader>tr", [[luaeval("require('pantran').motion_translate()")]], opts)
vim.api.nvim_set_keymap("n", "<leader>trr", [[luaeval("require('pantran').motion_translate() .. '_'")]], opts)
vim.api.nvim_set_keymap("x", "<leader>tr", [[luaeval("require('pantran').motion_translate()")]], opts)

The mappings work similarly to the command in that they also allow you to use ranges. E.g., you can use 3<leader>trr to populate the translation window with the next three lines of text. One advantage over the command, however, is the additional support for text objects. You can use <leader>tris or <leader>trip to translate the surrounding sentence or paragraph, for example. Other translation modes like replacing or appending text immediately without opening an interactive window are also implemented. Again, consult the documentation for more details.


The plugin already supports a few different translation engines. If you have any further suggestions feel free to open an issue or pull request! The currently supported engines are as follows:

Some of these engines are free and open-source and can be used right off the bat. However, some are commercial and might require additional setup steps. For stability reasons, the philosophy of this plugin is to prioritize official API endpoints for which commercial engines usually require some means of authentication, e.g., through an API key. If no such key is configured but free alternative endpoints exist, these are used as fallback options. Note, however, that these are often severely rate-limited and in some instances produce inferior translations. So if you want to use a commercial engine, configuring authentication is usually recommended (see the docs for more information).


Pantran.nvim supports a wide range of configuration options. Some essential ones are listed below, for a full list consult the additional documentation. The invocation of require("pantran").setup() is optional.

  -- Default engine to use for translation. To list valid engine names run
  -- `:lua =vim.tbl_keys(require("pantran.engines"))`.
  default_engine = "argos",
  -- Configuration for individual engines goes here.
  engines = {
    yandex = {
      -- Default languages can be defined on a per engine basis. In this case
      -- `:lua require("pantran.async").run(function()
      -- vim.pretty_print(require("pantran.engines").yandex:languages()) end)`
      -- can be used to list available language identifiers.
      default_source = "auto",
      default_target = "en"
  controls = {
    mappings = {
      edit = {
        n = {
          -- Use this table to add additional mappings for the normal mode in
          -- the translation window. Either strings or function references are
          -- supported.
          ["j"] = "gj",
          ["k"] = "gk"
        i = {
          -- Similar table but for insert mode. Using 'false' disables
          -- existing keybindings.
          ["<C-y>"] = false,
          ["<C-a>"] = require("pantran.ui.actions").yank_close_translation
      -- Keybindings here are used in the selection window.
      select = {
        n = {
          -- ...