Translate comments and strings directly in Neovim using hover or immersive inline views. Supports classic translation APIs as well as LLM backends, including fully local models via Ollama.
Many translation plugins rely on external services only. comment-translate.nvim is designed for teams and individuals who want a practical choice:
- Use hosted providers when you want quality and speed.
- Use local LLMs when you need stronger privacy and control.
- Keep your translation workflow inside Neovim.
- LLM translation support (
openai,anthropic,gemini,ollama) - Local LLM workflow via Ollama (no source text sent to cloud APIs)
- Hover translation for quick understanding
- Immersive inline translation mode
- Replace selected text with translation
- Tree-sitter aware comment/string detection
This plugin gives you control over where your text goes:
translate_service = 'google'or hostedllmproviders: text is sent to the configured remote service.llm.provider = 'ollama'with the default local endpoint keeps translation local; ifllm.endpointis set to a remote host, text is sent there.- Cache is in-memory only and is not persisted to disk by this plugin.
For sensitive repositories, local Ollama models are the recommended setup.
- Neovim 0.8+
curl- plenary.nvim (required)
- nvim-treesitter (recommended)
Note: Internet is not required when you use local translation only (for example, Ollama running locally).
{
'noir4y/comment-translate.nvim',
dependencies = {
'nvim-lua/plenary.nvim',
'nvim-treesitter/nvim-treesitter',
},
config = function()
require('comment-translate').setup({})
end,
}use {
'noir4y/comment-translate.nvim',
requires = {
'nvim-lua/plenary.nvim',
'nvim-treesitter/nvim-treesitter',
},
config = function()
require('comment-translate').setup({})
end,
}vim.keymap.set('n', '<leader>th', '<cmd>CommentTranslateHover<CR>', { silent = true }):CommentTranslateToggle:CommentTranslateReplacerequire('comment-translate').setup({
target_language = 'ja',
translate_service = 'google', -- 'google' or 'llm'
hover = {
enabled = true,
delay = 500,
auto = true,
},
immersive = {
enabled = false,
},
cache = {
enabled = true,
max_entries = 1000,
},
targets = {
comment = true,
string = true,
},
llm = {
provider = 'ollama', -- 'openai' | 'anthropic' | 'gemini' | 'ollama'
model = 'translategemma:4b',
api_key = nil, -- not required for ollama
timeout = 20,
endpoint = 'http://localhost:11434/api/chat', -- optional
},
keymaps = {
hover = '<leader>th',
hover_manual = '<leader>tc',
replace = '<leader>tr',
toggle = '<leader>tt',
},
})require('comment-translate').setup({
translate_service = 'llm',
llm = {
provider = 'ollama',
model = 'translategemma:4b',
},
})require('comment-translate').setup({
translate_service = 'llm',
llm = {
provider = 'openai',
api_key = vim.env.OPENAI_API_KEY,
model = 'gpt-5.2',
},
}):CommentTranslateHover— Display translation under cursor:CommentTranslateHoverToggle— Toggle auto hover on/off:CommentTranslateReplace— Replace selected text with translation:CommentTranslateToggle— Toggle immersive translation globally:CommentTranslateUpdate— Update immersive translation for current buffer:CommentTranslateSetup— Setup plugin with default settings:CommentTranslateHealth— Health check (:checkhealth comment-translate)
- Format:
make fmt - Format check:
make fmt-check - Lint:
make lint - Test:
make test
MIT
