323 lines
12 KiB
EmacsLisp
323 lines
12 KiB
EmacsLisp
;;; google-translate-smooth-ui.el --- Just another UI to Google
|
|
;;; Translate package
|
|
|
|
;; Copyright (C) 2012 Oleksandr Manzyuk <manzyuk@gmail.com>
|
|
|
|
;; Author: Oleksandr Manzyuk <manzyuk@gmail.com>
|
|
;; Maintainer: Andrey Tykhonov <atykhonov@gmail.com>
|
|
;; URL: https://github.com/atykhonov/google-translate
|
|
;; Version: 0.11.18
|
|
;; Keywords: convenience
|
|
|
|
;; Contributors:
|
|
;; Tassilo Horn <tsdh@gnu.org>
|
|
;; Bernard Hurley <bernard@marcade.biz>
|
|
;; Chris Bilson <cbilson@pobox.com>
|
|
;; Takumi Kinjo <takumi.kinjo@gmail.com>
|
|
;; momomo5717 <momomo5717@gmail.com>
|
|
|
|
;; This file is NOT part of GNU Emacs.
|
|
|
|
;; This is free software; you can redistribute it and/or modify it
|
|
;; under the terms of the GNU General Public License as published by
|
|
;; the Free Software Foundation; either version 2, or (at your option)
|
|
;; any later version.
|
|
|
|
;; This file is distributed in the hope that it will be useful, but
|
|
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
;; General Public License for more details.
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
;;; Commentary:
|
|
|
|
;; `google-translate-smooth-ui' is a just alternative to the default
|
|
;; `google-translate-default-ui'. It was written with mind to provide
|
|
;; impoved user interface and, especially, to achieve better
|
|
;; supporting of many default languages. `google-translate-default-ui'
|
|
;; supports two default languages very well but there is no space for
|
|
;; the third one.
|
|
;;
|
|
;; Invoking the function `google-translate-smooth-translate' queries
|
|
;; text and (optionally) the source and target languages to translate,
|
|
;; and shows a buffer with available translations of the text.
|
|
|
|
;; Installation:
|
|
|
|
;; Assuming that the files `google-translate.el',
|
|
;; `google-translate-core.el', `google-translate-core-ui.el' and
|
|
;; `google-translate-smooth-ui.el' are somewhere on the load path, add
|
|
;; the following lines to your .emacs file:
|
|
;;
|
|
;; (require 'google-translate-smooth-ui)
|
|
;; (global-set-key "\C-ct" 'google-translate-smooth-translate)
|
|
;;
|
|
;; Change the key bindings to your liking.
|
|
;;
|
|
;; Configuration:
|
|
;;
|
|
;; `google-translate-translation-directions-alist' alist is intended
|
|
;; to contain translation directions.
|
|
;;
|
|
;; For example it could be defined (in your .emacs or init.el) as:
|
|
;;
|
|
;; (setq google-translate-translation-directions-alist '(("en" . "ru"))
|
|
;;
|
|
;; in this way one translation direction ("en" > "ru") is defined and
|
|
;; when `google-translate-smooth-translate' function executes it will
|
|
;; output the prompt (in minibuffer) which will looks like as the
|
|
;; following:
|
|
;;
|
|
;; [English > Russian] Translate:
|
|
;;
|
|
;; You may set as many translation directions as you would like
|
|
;; to. For example such piece of code will define four translation
|
|
;; directions:
|
|
;;
|
|
;; (setq google-translate-translation-directions-alist
|
|
;; '(("de" . "en") ("en" . "de") ("de" . "fr") ("fr" . "de")))
|
|
;;
|
|
;; in this way, when `google-translate-smooth-translate' function
|
|
;; executes you'll be queried by the prompt which will looks like the
|
|
;; following:
|
|
;;
|
|
;; [German > English] Translate:
|
|
;;
|
|
;; and, also in this way, you'll be able to switch between different
|
|
;; translation directions directly from minibuffer by using "C-n" and
|
|
;; "C-p" key bindings. "C-n" key binding changes current translation
|
|
;; direction to the next direction defined in the
|
|
;; `google-translate-translation-directions-alist' variable. And "C-p"
|
|
;; key binding changes current translation direction to the previous
|
|
;; one. Thus, while executing `google-translate-smooth-translate'
|
|
;; function and having in minibuffer such prompt:
|
|
;;
|
|
;; [German > English] Translate:
|
|
;;
|
|
;; then after pressing "C-n" you'll get the following prompt:
|
|
;;
|
|
;; [English > German] Translate:
|
|
;;
|
|
;; By default `google-translate-translation-directions-alist' is empty
|
|
;; and thus during execution of `google-translate-smooth-translate'
|
|
;; you'll be queried (to input a text) by the prompt:
|
|
;;
|
|
;; Translate:
|
|
;;
|
|
;; And after inputed text you'll be queried also for the source and
|
|
;; target languages. To let the package to be known which languages
|
|
;; you would like to always use and to avoid repetitive language
|
|
;; quering it is reasonable to define them in the mentioned
|
|
;; `google-translate-translation-directions-alist' variable.
|
|
|
|
;; Customization:
|
|
|
|
;; `google-translate-smooth-ui' doesn't contain any customizable
|
|
;; variables. But `google-translate-smooth-ui' extends
|
|
;; `google-translate-core-ui' and thus it could be customized via this
|
|
;; package's variables. Please read documentation for the
|
|
;; `google-translate-core-ui' package.
|
|
;;
|
|
|
|
;;; Code:
|
|
|
|
|
|
(require 'google-translate-core-ui)
|
|
|
|
|
|
(defgroup google-translate-smooth-ui nil
|
|
"Just Another UI for Google Translate package."
|
|
:group 'processes)
|
|
|
|
(defvar google-translate-translation-directions-alist
|
|
'()
|
|
"Alist of translation directions. Each of direction could be
|
|
selected directly in the minibuffer during translation.
|
|
|
|
Each element is a cons-cell of the form (SOURCE_CODE
|
|
. TARGET_CODE), where SOURCE_CODE is a source language code and
|
|
TARGET_CODE is a target language code.
|
|
|
|
Language codes are defined in
|
|
`google-translate-supported-languages-alist' variable.
|
|
|
|
As example, this alist could looks like the following:
|
|
|
|
'((\"en\" . \"ru\")
|
|
(\"ru\" . \"en\")
|
|
(\"uk\" . \"ru\")
|
|
(\"ru\" . \"uk\"))")
|
|
|
|
(defvar google-translate-current-translation-direction 0
|
|
"Points to nth element of
|
|
`google-translate-translation-directions-alist' variable and
|
|
keeps current translation direction while changing translation
|
|
directions.")
|
|
|
|
(defvar google-translate-translation-direction-query ""
|
|
"Temporal variable which keeps a minibuffer text while
|
|
switching translation directions.")
|
|
|
|
(defvar google-translate-try-other-direction nil
|
|
"Indicates that other translation direction is going to be
|
|
used.")
|
|
|
|
(defvar google-translate-minibuffer-keymap nil
|
|
"Keymap for minibuffer for changing translation directions.")
|
|
|
|
(defun google-translate-change-translation-direction (direction)
|
|
"Change translation direction. If DIRECTION is 'next then
|
|
change current direction by the next one. Otherwise change it to
|
|
the previous one."
|
|
(let ((current google-translate-current-translation-direction)
|
|
(length (length google-translate-translation-directions-alist)))
|
|
(setq current
|
|
(if (equal direction 'next)
|
|
(+ current 1)
|
|
(- current 1)))
|
|
(when (< current 0)
|
|
(setq current (- length 1)))
|
|
(when (> current (- length 1))
|
|
(setq current 0))
|
|
(setq google-translate-current-translation-direction current)
|
|
(setq google-translate-translation-direction-query
|
|
(minibuffer-contents))))
|
|
|
|
(defun google-translate-next-translation-direction ()
|
|
"Switch to the next translation direction. If current direction
|
|
is the last in the list of existing directions then switch to the
|
|
first one."
|
|
(interactive)
|
|
(google-translate-change-translation-direction 'next)
|
|
(setq google-translate-try-other-direction t)
|
|
(exit-minibuffer))
|
|
|
|
(defun google-translate-previous-translation-direction ()
|
|
"Switch to the previous translation direction. If current
|
|
direction is the first in the list of existing directions then
|
|
switch to the last one."
|
|
(interactive)
|
|
(google-translate-change-translation-direction 'previous)
|
|
(setq google-translate-try-other-direction t)
|
|
(exit-minibuffer))
|
|
|
|
(defun google-translate-query-translate-using-directions ()
|
|
"Tranlate query using translation directions described by
|
|
`google-translate-translation-directions-alist' variable.
|
|
|
|
This function allows to select desired translation direction
|
|
directly in the minibuffer while translating a word or a
|
|
sentence.
|
|
|
|
This function defines two key bindings for the minibuffer which
|
|
allow to select direction:
|
|
C-p - to select previous direction,
|
|
C-n - to select next direction."
|
|
(interactive)
|
|
(let ((text ""))
|
|
(setq google-translate-try-other-direction nil)
|
|
(setq text
|
|
(if google-translate-input-method-auto-toggling
|
|
(minibuffer-with-setup-hook
|
|
(lambda ()
|
|
(google-translate-setup-preferable-input-method
|
|
(google-translate--current-direction-source-language)))
|
|
'google-translate-setup-preferable-input-method
|
|
(google-translate--read-from-minibuffer))
|
|
(google-translate--read-from-minibuffer)))
|
|
(if google-translate-try-other-direction
|
|
(call-interactively 'google-translate-query-translate-using-directions)
|
|
text)))
|
|
|
|
(defun google-translate--setup-minibuffer-keymap ()
|
|
"Setup additional key bindings for minibuffer."
|
|
(unless google-translate-minibuffer-keymap
|
|
(setq google-translate-minibuffer-keymap
|
|
(let ((map (make-sparse-keymap)))
|
|
(define-key map "\C-p" 'google-translate-previous-translation-direction)
|
|
(define-key map "\C-n" 'google-translate-next-translation-direction)
|
|
(define-key map "\C-l" 'google-translate-clear-minibuffer)
|
|
(set-keymap-parent map minibuffer-local-map)
|
|
map))))
|
|
|
|
(defun google-translate-clear-minibuffer ()
|
|
"Delete minibuffer contents."
|
|
(interactive)
|
|
(delete-minibuffer-contents))
|
|
|
|
(defun google-translate--read-from-minibuffer ()
|
|
"Read string from minibuffer."
|
|
(let* ((source-language
|
|
(google-translate--current-direction-source-language))
|
|
(target-language
|
|
(google-translate--current-direction-target-language))
|
|
(prompt (if (or (null source-language)
|
|
(null target-language))
|
|
"Translate: "
|
|
(format "[%s > %s] Translate: "
|
|
(google-translate-language-display-name source-language)
|
|
(google-translate-language-display-name target-language)))))
|
|
(google-translate--setup-minibuffer-keymap)
|
|
(read-from-minibuffer
|
|
prompt
|
|
google-translate-translation-direction-query
|
|
google-translate-minibuffer-keymap nil nil
|
|
google-translate-translation-direction-query t)))
|
|
|
|
(defun google-translate--current-direction-source-language ()
|
|
"Retrieve source language from the current translation
|
|
direction."
|
|
(car (nth google-translate-current-translation-direction
|
|
google-translate-translation-directions-alist)))
|
|
|
|
(defun google-translate--current-direction-target-language ()
|
|
"Retrieve target language from the current translation
|
|
direction."
|
|
(cdr (nth google-translate-current-translation-direction
|
|
google-translate-translation-directions-alist)))
|
|
|
|
;;;###autoload
|
|
(defun google-translate-smooth-translate ()
|
|
"Translate a text using translation directions.
|
|
|
|
Make a prompt in minibuffer for a text to translate. Default text
|
|
is word at point.
|
|
|
|
In case of `google-translate-translation-directions-alist' is
|
|
empty list then after inputed translating text prompts for source
|
|
language and then for target languages.
|
|
|
|
In case of `google-translate-translation-directions-alist' is not
|
|
empty list takes current translation direction and makes
|
|
appropriate translation. Current translation direction indicates
|
|
in the minibuffers' prompt.
|
|
|
|
A current translation direction could be changed directly in the
|
|
minibuffer by means of key bindings such as C-n and C-p for
|
|
changing to the next translation direction and to the previous
|
|
one respectively."
|
|
(interactive)
|
|
|
|
(setq google-translate-translation-direction-query
|
|
(if (use-region-p)
|
|
(google-translate--strip-string
|
|
(buffer-substring-no-properties (region-beginning) (region-end)))
|
|
(current-word t t)))
|
|
|
|
(setq google-translate-current-translation-direction 0)
|
|
|
|
(let* ((text (google-translate-query-translate-using-directions))
|
|
(source-language (google-translate--current-direction-source-language))
|
|
(target-language (google-translate--current-direction-target-language)))
|
|
(when (null source-language)
|
|
(setq source-language (google-translate-read-source-language)))
|
|
(when (null target-language)
|
|
(setq target-language (google-translate-read-target-language)))
|
|
(google-translate-translate source-language target-language text)))
|
|
|
|
|
|
(provide 'google-translate-smooth-ui)
|
|
|
|
;;; google-translate-smooth-ui.el ends here
|