Reverso Context in Emacs

If you are an emacser, you are probably already following the Sacha Chua’s blog. If you are not, you should. Sacha maintains an incredible blog on Emacs-related news, upcoming events, Org Mode, configuration, new packages, and many other things from the Emacs world.

English is not my native language so I need the right tools to improve my language skills. My favorite tool is the Reverso web service, an AI-powered service for translation, grammar check, context, and synonyms search.

Of course, I’d prefer to use it in Emacs directly, and in one of the latest Sacha’s posts I found what I had been searching for - reverso.el.

At the time of writing, the package isn’t yet available anywhere but in the author’s GitHub repository, so as a first step you need either to download or to clone this package to your box.

I’ve cloned it to my ~/emacs.d/extras/.

git clone https://github.com/SqrtMinusOne/reverso.el.git

Secondly, you need to add this directory to your load-path and require the package.

(add-to-list 'load-path "~/.emacs.d/extras/reverso.el/")

Almost done.

Because I’m using Reverso quite often, I decided to implement a smart start-up function and to bind it to a common key like <F9>. I want to distinguish between the Translation (applied to a single word) and the Context (applied to a phrase or a sentence) features of Reverso. So now if you press <F9> and there is some region selected (active, in terminology of Emacs), reverso-context is called, else, if no region selected, reverso-translate is called for a word under the cursor.

;; Reverso context
;; https://github.com/SqrtMinusOne/reverso.el
(require 'reverso)

(defun avs/reverso ()
  "Calls `reverso' functions depending on selection.
If a region (selection) is active, calls `reverso-context',
otherwise calls `reverso-translate' for a word under the cursor."
  (interactive)
  (if (region-active-p)
      ;; Region is active, use context.
      (reverso-context)
    ;; Region is not active, get word coordinates...
    (let ((bounds (bounds-of-thing-at-point 'word))
          (p (point))
          )
      (if bounds
          (progn
            ;; ...select the word under cursor...
            (goto-char (car bounds))
            (set-mark-command nil)
            (goto-char (cdr bounds))
            ;; ...and translate it.
            (reverso-translate)
            ;; Then back to the initial position.
            (deactivate-mark)
            (goto-char p)
            )
        (error "No word under cursor!")
        )
      )
    )
  )

(global-set-key [(f9)] #'avs/reverso)

The word 'deposed' is under the cursor, no region is active, <F9> calls `reverso-translate'.

The region 'different kind of weather' is active, <F9> calls `reverso-context'

Many thanks to Pavel Korytov for the excellent packages, and, indeed, to Sacha Chua for pointing it out to all of us.