はっくはっくキッチン
Hack Hack Kitchen

gptel-translate.el: Translation support for gptel

 2026/02/01

gptel-translate.el is a package that adds translation support to gptel. It sends the text you want to translate along with the source and target languages to an LLM (large-language model) and returns the translation result.

  • Any LLM that gptel can use (OpenAI, Gemini, Ollama, …) can be employed directly.

  • The prompt is automatically adapted to the chosen model.

  • The source and target languages for translation can be changed at any time using the mini-buffer completion feature.

Disclaimer

This package is in alpha state and may undergo breaking changes.

Installation and Configuration

  1. Fetch the package

    git clone https://github.com/TPKato/gptel-translate.git ~/.emacs.d/site-lisp/gptel-translate
  2. Load and customize the package

    Below is an example that uses use-package.

    (use-package gptel-translate
      :load-path "site-lisp/gptel-translate"
    
      :config
      ;; Optional gptel configuration (e.g. adding models).
      ;; You may configure it here or, preferably, via
      ;; (use-package gptel ...).
      (gptel-make-openai "ollama"
        :host "localhost:11434"
        :protocol "http"
        :endpoint "/v1/chat/completions"
        :stream t
        :models '(translategemma:4b mitmul/plamo-2-translate:latest))
    
      :custom
      ;; Default languages (used when a buffer has no language
      ;; configuration)
      (gptel-translate-default-lang-from "Japanese")
      (gptel-translate-default-lang-to   "English")
    
      :bind            ; optional
      (("C-c t" . gptel-translate-mode)))

Usage (Example)

  1. Select model on gptel

    Launch gptel and select the LLM model you want to translate with.

    M-x gptel-menu RET -m  ;; choose a model
    M-x gptel              ;; start gptel's interactive mode
  2. Enable gptel-translate-mode

    M-x gptel-translate-mode

    Or press the key you bound via use-package (e.g. C-c t).

  3. Send text

    1. Enter the text you want to translate in gptel's input area.

    2. Run M-x gptel-send (C-c C-m). If the source or target language is not set, you'll be prompted in the minibuffer.

    3. C-u M-x gptel-send (C-u C-c C-m) lets you re-configure the language pair interactively. Enter rev as the source language to swap the current source/target pair.

Commands

gptel-translate-mode

Toggle the translation mode.

gptel-translate-change-languages

Interactively set the language pair. Specifying rev when choosing the source swaps the source/target.

gptel-translate-swap-languages

Swap the currently set source/target.

Behavior of gptel-send

When gptel-translate-mode is active, gptel-send behaves as follows:

M-x gptel-send

sends the prompt to the LLM.

C-u M-x gptel-send

prompts the user for the translation languages before sending.

C-u C-u M-x gptel-send

Same as the original C-u M-x gptel-send: it launches gptel-menu.

Translation-Model Group Configuration

gptel-translate.el defines and manages translation-model groups. Each group consists of:

  • an identifier

  • one or more LLM models

  • supported languages

  • a prompt-transformation function

Default translation-model groups

The following groups are registered by default (languages are omitted for brevity). See the source code for details.

"translategemma"
 :models    '(translategemma:4b translategemma:12b)
 :languages '( ... )
 :transform #'gptel-translate--transform-translategemma
"plamo-translate"
 :models    '(plamo-2-translate mmnga/plamo-2-translate-gguf mitmul/plamo-2-translate)
 :languages '( ... )
 :transform #'gptel-translate--transform-plamo

There is also a fallback group:

gptel-translate-generic-group-name
 :languages '( ... )
 :transform #'gptel-translate--transform-generic

If the current model is not covered by any registered group, the fallback group is used.

Adding a custom translation-model group

You can create your own group as follows. If a group with the same name already exists, it will be overwritten.

(defun gptel-translate--transform-mymodel (srclang dstlang)
  ;; Insert your prompt-transformation logic here.
  ;;
  ;; Refer to https://gptel.org/manual.html#orgbd9b14b
  ;; (9. Configuration > 9.1. The anatomy of gptel-send)
  )

(gptel-translate-make-model-group
 "my-model-group"        ; unique model-group name
 :models    '(model-1 model-2)
 :languages '("Japanese" "German" "English" "French")
 :transform #'gptel-translate--transform-mymodel)
Identifier (string)

The first argument, a unique group name.

:models (list of symbols)

The LLM models to use.

:languages (list of strings)

Language completion candidates when specifying source/target; you need not list every language the model supports.

:transform (function)

Prompt-transformation routine.

Partially updating a translation-model group

If you wish to change only part of an existing group, use gptel-translate-update-model-group.

(gptel-translate-update-model-group
 "my-group"
 :languages '("Japanese" "English")
 :models '(model-1 model-2))

This will overwrite the :languages and :models slots for the group named my-group, but leaves the :transform slot untouched.

If you wish to change the languages of the model group used as a fallback, you can do so using the following code:

(gptel-translate-update-model-group
 gptel-translate-generic-group-name
 :languages '("English" "German"))

Technical Background (Internal Structure)

When gptel-translate.el is loaded, the following actions are performed:

  • gptel-send is advised with gptel-translate--advice-gptel-send. This changes the behavior of the C-u prefix.

  • gptel-translate--prompt-transform is added to the gptel-prompt-transform-functions hook.

When gptel-translate-mode is non-nil and gptel-send is executed, gptel-translate--prompt-transform is invoked via the gptel-prompt-transform-functions hook. This function retrieves and executes the appropriate routine from the defined translation-model group that matches the current model, thereby modifying the LLM prompt to suit that model before sending.

If gptel-translate-mode is nil, neither gptel-translate--advice-gptel-send nor gptel-translate--prompt-transform affect the normal behavior of gptel-send.

Tested Environments

  • GNU Emacs 30.2 + gptel 0.9.9.3 on Arch Linux

  • LM Studio 0.3.37 on Windows 11

    • mmnga/plamo-2-translate-gguf

  • Ollama 0.14.0 on Windows 11

    • mitmul/plamo-2-translate:latest

    • translategemma:4b

License

  • GPL-3.0