mirror of
https://github.com/SqrtMinusOne/reverso.el.git
synced 2025-12-10 07:43:03 +03:00
feat: things generally seem to work
This commit is contained in:
parent
8a775d63c8
commit
c9481d7b3a
1 changed files with 258 additions and 61 deletions
319
reverso.el
319
reverso.el
|
|
@ -1,4 +1,4 @@
|
|||
;;; reverso.el --- Client for the https://reverso.net translation service -*- lexical-binding: t -*-
|
||||
;;; reverso.el --- Translation, grammar checking and bilingual concordances -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2022 Korytov Pavel
|
||||
|
||||
|
|
@ -31,11 +31,12 @@
|
|||
(require 'request)
|
||||
(require 'transient)
|
||||
(require 'url-util)
|
||||
(require 'dom)
|
||||
|
||||
(declare-function evil-define-key* "evil-core")
|
||||
|
||||
(defgroup reverso nil
|
||||
"Client for the https://reverso.net translation service."
|
||||
"Translation, grammar checking and bilingual concordances."
|
||||
:group 'applications)
|
||||
|
||||
(defface reverso-highlight-face
|
||||
|
|
@ -50,12 +51,17 @@
|
|||
|
||||
(defface reverso-heading-face
|
||||
'((t (:inherit transient-heading)))
|
||||
"Face for heading in reverso buffers."
|
||||
"Face for headings in reverso buffers."
|
||||
:group 'reverso)
|
||||
|
||||
(defface reverso-language-face
|
||||
(defface reverso-keyword-face
|
||||
'((t (:inherit transient-value)))
|
||||
"Face for language names in reverso buffers."
|
||||
"Face for various keywords in reverso buffers."
|
||||
:group 'reverso)
|
||||
|
||||
(defface reverso-definition-face
|
||||
'((t (:inherit italic)))
|
||||
"Face for word definitions in reverso buffer."
|
||||
:group 'reverso)
|
||||
|
||||
(defcustom reverso-max-display-lines-in-input 5
|
||||
|
|
@ -105,9 +111,9 @@ This one is used for the translation queries.")
|
|||
(portuguese . pt)
|
||||
(romanian . ro)
|
||||
(russian . ru))
|
||||
"Mapping from long language names to short ones.
|
||||
"Another mapping from long language names to short ones.
|
||||
|
||||
This one is used for the synonyms queries.")
|
||||
This one is used for the synonym queries.")
|
||||
|
||||
(defconst reverso--right-to-left-languages
|
||||
'(arabic hebrew)
|
||||
|
|
@ -131,7 +137,6 @@ This one is used for the synonyms queries.")
|
|||
russian)))
|
||||
"Available languages for diferent operations.")
|
||||
|
||||
|
||||
(defconst reverso--languages-compatible
|
||||
`((context
|
||||
. ((arabic . (english german spanish french hebrew italian
|
||||
|
|
@ -205,10 +210,10 @@ This one is used for the synonyms queries.")
|
|||
portuguese romanian ukrainian))
|
||||
(ukrainian . (english))
|
||||
(chinese . (english french spanish ukrainian)))))
|
||||
"Which languages are compatible with which.")
|
||||
"Compatibility of languages for different operations.")
|
||||
|
||||
(defun reverso-verify-settings ()
|
||||
"Check if all the languages are set correctly."
|
||||
"Check if the settings are correct."
|
||||
(interactive)
|
||||
(let ((languages (mapcar #'car reverso--language-mapping)))
|
||||
(dolist (cell reverso--languages)
|
||||
|
|
@ -256,7 +261,7 @@ A random one is be picked at package initialization.")
|
|||
(defvar reverso--user-agent
|
||||
(nth (random (length reverso--user-agents))
|
||||
reverso--user-agents)
|
||||
"User-Agent to use for reverse.el requests.")
|
||||
"User-Agent to use for reverso.el requests.")
|
||||
|
||||
(defun reverso--translate (text source target cb)
|
||||
"Translate TEXT from language SOURCE to TARGET.
|
||||
|
|
@ -265,11 +270,10 @@ SOURCE and TARGET are keys of `reverso--languages'. CB is called with
|
|||
the result.
|
||||
|
||||
The result is an alist with the following keys:
|
||||
- `:corrected-text': set when the text has been corrected
|
||||
- `:corrected-text': corrected version of SOURCE (if available)
|
||||
- `:language-from': the source language
|
||||
- `:language-to': the target language
|
||||
- `:detected-language': set when the detected target language is
|
||||
different from the source language
|
||||
- `:detected-language': the detected source language
|
||||
- `:translation': a string with translated text
|
||||
- `:context-results': a list with found contexts.
|
||||
An item of the list is an alist with the keys:
|
||||
|
|
@ -315,7 +319,7 @@ The result is an alist with the following keys:
|
|||
(message "Error!: %S" error-thrown)))))
|
||||
|
||||
(defun reverso--convert-string (dom)
|
||||
"Convert html DOM from the reverso API to fontified string.
|
||||
"Convert DOM from the reverso API to fontified string.
|
||||
|
||||
reverso.net uses tags to highlight relevant works, e.g. <em> for the
|
||||
selected word in the context search. This function fontifies words
|
||||
|
|
@ -393,14 +397,14 @@ ALIST is an alist, LOOKUP-VALUE is a value to look in `cdr'."
|
|||
(:context-results . ,context-results))))
|
||||
|
||||
(defun reverso--get-context (text source target cb)
|
||||
"Do a context translation for TEXT from SOURCE to TARGET.
|
||||
"Find bilingual concordances for TEXT.
|
||||
|
||||
SOURCE and TARGET are keys of `reverso--languages'. CB is called with
|
||||
the result.
|
||||
|
||||
The result is a list of alists with the keys:
|
||||
- `:source': string in the source language
|
||||
- `:target': string in the target language"
|
||||
- `:source': a string in the source language
|
||||
- `:target': the same string in the target language"
|
||||
(unless (and (alist-get source reverso--language-mapping)
|
||||
(member source
|
||||
(alist-get 'context reverso--languages)))
|
||||
|
|
@ -432,7 +436,7 @@ The result is a list of alists with the keys:
|
|||
(message "Error!: %S" error-thrown)))))
|
||||
|
||||
(defun reverso--get-context-parse (data)
|
||||
"Parse response from reverso context API into an alist.
|
||||
"Parse response from reverso context API.
|
||||
|
||||
DATA is an html string."
|
||||
(let ((html (with-temp-buffer
|
||||
|
|
@ -456,7 +460,7 @@ The result is a list of alists with the following keys:
|
|||
- `:kind': part of speech
|
||||
- `:synonyms': list of alists:
|
||||
- `:synonym': word
|
||||
- `:relevant': if t considered a \"good match\" by the service
|
||||
- `:relevant': if t, considered a \"good match\" by the service
|
||||
- `:examples': list of strings with examples
|
||||
- `:antonyms': list of alists
|
||||
- `:antonym': word"
|
||||
|
|
@ -521,6 +525,27 @@ HTML is a string."
|
|||
`((:antonym . ,text))))))))
|
||||
|
||||
(defun reverso--get-grammar (text language cb)
|
||||
"Check TEXT in LANGUAGE for errors.
|
||||
|
||||
CB is called with the result.
|
||||
|
||||
The result is an alist with the keys:
|
||||
`:corrected-text': corrected version of TEXT
|
||||
`:source-text-hl': TEXT with highlighted errors
|
||||
`:corrections': a list of alists with keys:
|
||||
- `:type': error type
|
||||
- `:short-description'
|
||||
- `:long-description'
|
||||
- `:mistake-text': part of TEXT with the error
|
||||
- `:correction-text': corrected version of `:mistake-text'
|
||||
- `:correction-defition': definiton of `:correction-text', if
|
||||
available
|
||||
- `:start-index': start index in TEXT
|
||||
- `:end-index': end index TEXT
|
||||
- `:suggestions': a list of alists with keys:
|
||||
- `:text': the suggested text
|
||||
- `:definition': definition of `:text', if available
|
||||
- `:category': category of the correction, if available"
|
||||
(unless (member language (alist-get 'grammar reverso--languages))
|
||||
(error "Wrong language: %s" language))
|
||||
(request (concat (alist-get 'grammar reverso--urls)
|
||||
|
|
@ -543,34 +568,39 @@ HTML is a string."
|
|||
(message "Error!: %S" error-thrown)))))
|
||||
|
||||
(defun reverso--get-grammar-parse (source-text data)
|
||||
"Parse the reverso grammar API response.
|
||||
|
||||
SOURCE-TEXT is the text sent for checking. DATA is the JSON reply."
|
||||
(let* ((corrected-text (alist-get 'text data))
|
||||
(source-text-hl
|
||||
(with-temp-buffer
|
||||
(insert source-text)
|
||||
(cl-loop for corr across (alist-get 'corrections data)
|
||||
if (alist-get 'startIndex corr)
|
||||
do (put-text-property (alist-get 'startIndex corr)
|
||||
(alist-get 'endIndex corr)
|
||||
do (put-text-property (1+ (alist-get 'startIndex corr))
|
||||
(+ 2 (alist-get 'endIndex corr))
|
||||
'face 'reverso-error-face))
|
||||
(buffer-string)))
|
||||
(corrections
|
||||
(cl-loop
|
||||
for corr across (alist-get 'corrections data)
|
||||
collect `((type . ,(alist-get 'type corr))
|
||||
(short-description . ,(alist-get 'shortDescription corr))
|
||||
(long-description . ,(alist-get 'longDescription corr))
|
||||
(mistake-text . ,(alist-get 'mistakeText corr))
|
||||
(correction-text . ,(alist-get 'correctionText corr))
|
||||
(correction-defition . ,(alist-get 'correctionDefinition corr))
|
||||
(suggestions
|
||||
collect `((:type . ,(alist-get 'type corr))
|
||||
(:short-description . ,(alist-get 'shortDescription corr))
|
||||
(:long-description . ,(alist-get 'longDescription corr))
|
||||
(:mistake-text . ,(alist-get 'mistakeText corr))
|
||||
(:correction-text . ,(alist-get 'correctionText corr))
|
||||
(:correction-defition . ,(alist-get 'correctionDefinition corr))
|
||||
(:start-index . ,(alist-get 'startIndex corr))
|
||||
(:end-index . ,(alist-get 'endIndex corr))
|
||||
(:suggestions
|
||||
. ,(cl-loop for s across (alist-get 'suggestions corr)
|
||||
collect
|
||||
`((text . ,(alist-get 'text s))
|
||||
(definition . ,(alist-get 'definition s))
|
||||
(category . ,(alist-get 'category s)))))))))
|
||||
`((corrected-text . ,corrected-text)
|
||||
(source-text . ,source-text-hl)
|
||||
(corrections . ,corrections))))
|
||||
`((:text . ,(alist-get 'text s))
|
||||
(:definition . ,(alist-get 'definition s))
|
||||
(:category . ,(alist-get 'category s)))))))))
|
||||
`((:corrected-text . ,corrected-text)
|
||||
(:source-text-hl . ,source-text-hl)
|
||||
(:corrections . ,corrections))))
|
||||
|
||||
;;; Buffers
|
||||
|
||||
|
|
@ -608,16 +638,16 @@ source text."
|
|||
(let ((multiline (string-match-p "\n" text)))
|
||||
(insert (propertize
|
||||
(symbol-name (alist-get :language-from data))
|
||||
'face 'reverso-language-face)
|
||||
'face 'reverso-keyword-face)
|
||||
" -> "
|
||||
(propertize
|
||||
(symbol-name (alist-get :language-to data))
|
||||
'face 'reverso-language-face))
|
||||
'face 'reverso-keyword-face))
|
||||
(when (alist-get :detected-language data)
|
||||
(insert " [detected: "
|
||||
(propertize
|
||||
(symbol-name (alist-get :detected-language data))
|
||||
'face 'reverso-language-face)
|
||||
'face 'reverso-keyword-face)
|
||||
"]"))
|
||||
(insert "\n\n")
|
||||
|
||||
|
|
@ -688,11 +718,11 @@ DATA is a list of alists with the following keys:
|
|||
for target = (alist-get :target datum)
|
||||
do (insert (propertize
|
||||
(format (format "%%-%ds: " lang-length) lang-to-name)
|
||||
'face 'reverso-language-face)
|
||||
'face 'reverso-keyword-face)
|
||||
source "\n"
|
||||
(propertize
|
||||
(format (format "%%%ds: " lang-length) lang-from-name)
|
||||
'face 'reverso-language-face)
|
||||
'face 'reverso-keyword-face)
|
||||
target "\n\n")))
|
||||
|
||||
(defun reverso--translate-render-brief (text data)
|
||||
|
|
@ -731,7 +761,7 @@ INPUT is the input string. DATA is a list as defined in
|
|||
(when (alist-get :kind datum)
|
||||
(insert (propertize
|
||||
"Part of speech: "
|
||||
'face 'reverso-language-face)
|
||||
'face 'reverso-keyword-face)
|
||||
(alist-get :kind datum)
|
||||
"\n"))
|
||||
(when (alist-get :synonyms datum)
|
||||
|
|
@ -760,6 +790,67 @@ INPUT is the input string. DATA is a list as defined in
|
|||
(insert "- " (alist-get :antonym antonym) "\n"))
|
||||
(insert "\n"))))
|
||||
|
||||
(defun reverso--grammar-render (data)
|
||||
"Render grammar checking results.
|
||||
|
||||
DATA is an alist as defined in `reverso--get-grammar'."
|
||||
(insert
|
||||
(propertize "Source text: " 'face 'reverso-heading-face)
|
||||
"\n"
|
||||
(alist-get :source-text-hl data)
|
||||
"\n\n"
|
||||
(propertize "Corrected text: " 'face 'reverso-heading-face)
|
||||
"\n"
|
||||
(alist-get :corrected-text data)
|
||||
"\n\n")
|
||||
(when (alist-get :corrections data)
|
||||
(insert
|
||||
(propertize "Corrections: " 'face 'reverso-heading-face)
|
||||
"\n")
|
||||
(dolist (corr (alist-get :corrections data))
|
||||
(insert
|
||||
(propertize (or (alist-get :type corr) "")
|
||||
'face 'reverso-keyword-face))
|
||||
(when (alist-get :short-description corr)
|
||||
(insert ": " (alist-get :short-description corr)))
|
||||
(insert "\n")
|
||||
(when (alist-get :long-description corr)
|
||||
(insert (alist-get :long-description corr))
|
||||
(insert "\n"))
|
||||
(insert "\n")
|
||||
(insert
|
||||
(propertize
|
||||
(or (alist-get :mistake-text corr) "")
|
||||
'face 'reverso-highlight-face)
|
||||
" -> "
|
||||
(propertize
|
||||
(or (alist-get :correction-text corr) "")
|
||||
'face 'reverso-highlight-face))
|
||||
(when (alist-get :correction-defition corr)
|
||||
(insert " [" (propertize
|
||||
(alist-get :correction-defition corr)
|
||||
'face 'reverso-definition-face)
|
||||
"]"))
|
||||
(insert "\n\n")
|
||||
(when (alist-get :suggestions corr)
|
||||
(insert "Suggestions:\n")
|
||||
(dolist (sg (alist-get :suggestions corr))
|
||||
(insert "- ")
|
||||
(when (alist-get :category sg)
|
||||
(insert (alist-get :category sg) ": "))
|
||||
(insert (propertize
|
||||
(alist-get :text sg)
|
||||
'face 'reverso-highlight-face))
|
||||
(when (alist-get :definition sg)
|
||||
(insert
|
||||
" ["
|
||||
(propertize
|
||||
(alist-get :definition sg)
|
||||
'face 'reverso-definition-face)
|
||||
"]"))
|
||||
(insert "\n"))
|
||||
(insert "\n")))))
|
||||
|
||||
(defmacro reverso--with-buffer (&rest body)
|
||||
"Execute BODY in the clean `reverso' results buffer."
|
||||
(declare (indent 0))
|
||||
|
|
@ -781,14 +872,25 @@ INPUT is the input string. DATA is a list as defined in
|
|||
((format :initform " %k %d: %v"))
|
||||
"Class used for retrieving the input string.")
|
||||
|
||||
(defvar reverso--use-buffer-as-input nil
|
||||
"Whether to use the current buffer as input.
|
||||
|
||||
That parameter is normally set by the prefix argument, but as it
|
||||
doesn't pesist between parent and child invocations, this variable is
|
||||
used instead.")
|
||||
|
||||
(cl-defmethod transient-init-value ((obj reverso--transient-input))
|
||||
"Initialize the value of `reverso--transient-input'.
|
||||
|
||||
OBJ is an instance of the class."
|
||||
(oset obj value
|
||||
(cond
|
||||
((and (slot-boundp obj 'value) (oref obj value))
|
||||
(oref obj value))
|
||||
((region-active-p)
|
||||
(buffer-substring-no-properties (region-beginning) (region-end)))
|
||||
((equal current-prefix-arg '(4))
|
||||
((or (equal current-prefix-arg '(4))
|
||||
reverso--use-buffer-as-input)
|
||||
(if reverso--output
|
||||
reverso--output
|
||||
(buffer-substring-no-properties (point-min) (point-max))))
|
||||
|
|
@ -796,9 +898,15 @@ INPUT is the input string. DATA is a list as defined in
|
|||
(t ""))))
|
||||
|
||||
(cl-defmethod transient-infix-read ((obj reverso--transient-input))
|
||||
"Read input string from the minibuffer.
|
||||
|
||||
OBJ is an instance of the `reverso--transient-input'."
|
||||
(read-from-minibuffer "Input: " (oref obj value)))
|
||||
|
||||
(cl-defmethod transient-format-value ((obj reverso--transient-input))
|
||||
"Format the input string for display in the transient buffer.
|
||||
|
||||
OBJ is an instance of `reverso--transient-input'."
|
||||
(propertize
|
||||
(with-temp-buffer
|
||||
(insert (oref obj value))
|
||||
|
|
@ -830,24 +938,47 @@ INPUT is the input string. DATA is a list as defined in
|
|||
(is-target :initarg :is-target :initform nil))
|
||||
"Class used for switching the language.")
|
||||
|
||||
(defvar reverso--source-value nil)
|
||||
(defvar reverso--source-value nil
|
||||
"Selected source language in `reverso'.
|
||||
|
||||
(defvar reverso--target-value nil)
|
||||
Used for persistence between invocations of transient buffers.")
|
||||
|
||||
(defvar reverso--prefer-brief nil)
|
||||
(defvar reverso--target-value nil
|
||||
"Selected target language in `reverso'.
|
||||
|
||||
(defun reverso--get-available-languages (obj &optional target-languages-list is-target)
|
||||
Used for persistence between invocations of transient buffers.")
|
||||
|
||||
(defvar reverso--prefer-brief nil
|
||||
"If non-nil, select brief translation display by default.
|
||||
|
||||
Used for persistence between invocations of transient buffers.")
|
||||
|
||||
(defun reverso--get-available-languages (obj)
|
||||
"Get available languages for the operation.
|
||||
|
||||
OBJ is an instance of transient infix. It needs to have the following
|
||||
slots:
|
||||
- `languages': list of available languages
|
||||
- `is-target': if OBJ selects a target language
|
||||
- `target-languages': alist, where the key is a source language, and
|
||||
the value is a list of available target languages for that source
|
||||
language.
|
||||
|
||||
If `is-target' is non-nil, then selection of languages has to limited.
|
||||
In that case, `reverso--source-value' is used to get the source
|
||||
language."
|
||||
(let* ((all-languages
|
||||
(seq-sort
|
||||
(lambda (a b) (string-lessp (symbol-name a)
|
||||
(symbol-name b)))
|
||||
(or (oref obj languages)
|
||||
(mapcar #'car reverso--language-mapping))))
|
||||
(is-target (oref obj is-target))
|
||||
(source-language (when is-target
|
||||
(or reverso--source-value
|
||||
(car all-languages))))
|
||||
(target-languages (when (and is-target target-languages-list)
|
||||
(alist-get source-language target-languages-list)))
|
||||
(target-languages (when (and is-target (oref obj target-languages))
|
||||
(alist-get source-language (oref obj target-languages))))
|
||||
(languages (cl-loop for lang in all-languages
|
||||
if (or (not source-language)
|
||||
(not (eq source-language lang)))
|
||||
|
|
@ -861,11 +992,18 @@ INPUT is the input string. DATA is a list as defined in
|
|||
(seq-intersection intersection-1 target-languages))))))
|
||||
|
||||
(defun reverso--get-language-variable (obj)
|
||||
"Get the name of the variable that stores the selected language.
|
||||
|
||||
OBJ is an instance of a transient infix, that has to have a slot
|
||||
called `is-target'."
|
||||
(if (oref obj is-target)
|
||||
'reverso--target-value
|
||||
'reverso--source-value))
|
||||
|
||||
(cl-defmethod transient-init-value ((obj reverso--transient-language))
|
||||
"Initialize the value for the language picker.
|
||||
|
||||
OBJ is an instance of `reverso--transient-language'."
|
||||
(let ((value
|
||||
(cond
|
||||
((and (slot-boundp obj 'value) (oref obj value))
|
||||
|
|
@ -880,6 +1018,9 @@ INPUT is the input string. DATA is a list as defined in
|
|||
(oset obj value value)))
|
||||
|
||||
(cl-defmethod transient-format-value ((obj reverso--transient-language))
|
||||
"Format the value of the language picker.
|
||||
|
||||
OBJ is an instance of `reverso--transient-language'."
|
||||
(let ((value (transient-infix-value obj)))
|
||||
(concat
|
||||
(propertize "[" 'face 'transient-inactive-value)
|
||||
|
|
@ -889,18 +1030,15 @@ INPUT is the input string. DATA is a list as defined in
|
|||
(if (eq choice value)
|
||||
'transient-value
|
||||
'transient-inactive-value)))
|
||||
(reverso--get-available-languages
|
||||
obj
|
||||
(oref obj target-languages)
|
||||
(oref obj is-target))
|
||||
(reverso--get-available-languages obj)
|
||||
(propertize "|" 'face 'transient-inactive-value))
|
||||
(propertize "]" 'face 'transient-inactive-value))))
|
||||
|
||||
(cl-defmethod transient-infix-read ((obj reverso--transient-language))
|
||||
(let* ((choices (reverso--get-available-languages
|
||||
obj
|
||||
(oref obj target-languages)
|
||||
(oref obj is-target)))
|
||||
"Pick a value in the language picker.
|
||||
|
||||
OBJ is an instance of `reverso--transient-language'."
|
||||
(let* ((choices (reverso--get-available-languages obj))
|
||||
(current-idx (or (cl-position (oref obj value) choices) -1))
|
||||
(next-idx (% (1+ current-idx) (length choices)))
|
||||
(next-choice
|
||||
|
|
@ -917,10 +1055,10 @@ INPUT is the input string. DATA is a list as defined in
|
|||
next-choice))
|
||||
|
||||
(cl-defmethod transient-infix-value ((obj reverso--transient-language))
|
||||
(let* ((choices (reverso--get-available-languages
|
||||
obj
|
||||
(oref obj target-languages)
|
||||
(oref obj is-target)))
|
||||
"Get the current value of the language picker.
|
||||
|
||||
OBJ is an instance of `reverso--transient-language'."
|
||||
(let* ((choices (reverso--get-available-languages obj))
|
||||
(current-idx (or (cl-position (oref obj value) choices) -1)))
|
||||
(nth current-idx choices)))
|
||||
|
||||
|
|
@ -928,10 +1066,15 @@ INPUT is the input string. DATA is a list as defined in
|
|||
"Toggle brief output.")
|
||||
|
||||
(cl-defmethod transient-init-value ((obj reverso--transient-brief))
|
||||
"Initialize the value of the brief output switcher.
|
||||
|
||||
OBJ is an instance of `reverso--transient-brief'."
|
||||
(oset obj value reverso--prefer-brief))
|
||||
|
||||
(cl-defmethod transient-infix-read ((obj reverso--transient-brief))
|
||||
"Toggle the switch on or off."
|
||||
"Toggle the switch on or off.
|
||||
|
||||
OBJ is an instance of `reverso--transient-brief'."
|
||||
(setq reverso--prefer-brief
|
||||
(null (oref obj value))))
|
||||
|
||||
|
|
@ -997,6 +1140,7 @@ INPUT is the input string. DATA is a list as defined in
|
|||
(reverso--translate-render input data))))))
|
||||
|
||||
(transient-define-prefix reverso-translate ()
|
||||
"Translate text."
|
||||
["Input"
|
||||
("i" "Input" reverso--transient-input-infix)]
|
||||
["Parameters"
|
||||
|
|
@ -1036,6 +1180,10 @@ INPUT is the input string. DATA is a list as defined in
|
|||
(setq-local reverso--data data)))))
|
||||
|
||||
(transient-define-prefix reverso-context ()
|
||||
"Find bilingual concordances for text.
|
||||
|
||||
A bilingual concordance is a pair of strings of the same text in
|
||||
different languages."
|
||||
["Input"
|
||||
("i" "Input" reverso--transient-input-infix)]
|
||||
["Parameters"
|
||||
|
|
@ -1065,6 +1213,7 @@ INPUT is the input string. DATA is a list as defined in
|
|||
(setq-local reverso--data data)))))
|
||||
|
||||
(transient-define-prefix reverso-synonyms ()
|
||||
"Find synomyms."
|
||||
["Input"
|
||||
("i" "Input" reverso--transient-input-infix)]
|
||||
["Parameters"
|
||||
|
|
@ -1073,5 +1222,53 @@ INPUT is the input string. DATA is a list as defined in
|
|||
(reverso--synonyms-exec-suffix)
|
||||
("q" "Quit" transient-quit-one)])
|
||||
|
||||
(transient-define-infix reverso--transient-grammar-language ()
|
||||
:class 'reverso--transient-language
|
||||
:description "Language"
|
||||
:key "s"
|
||||
:argument "-s"
|
||||
:languages (alist-get 'grammar reverso--languages))
|
||||
|
||||
(transient-define-suffix reverso--grammar-exec-suffix (input source)
|
||||
:key "e"
|
||||
:description "Check grammar"
|
||||
(interactive (transient-args transient-current-command))
|
||||
(reverso--get-grammar
|
||||
input source
|
||||
(lambda (data)
|
||||
(reverso--with-buffer
|
||||
(reverso--grammar-render data)
|
||||
(setq-local reverso--data data)))))
|
||||
|
||||
(transient-define-prefix reverso-grammar ()
|
||||
"Check grammar."
|
||||
["Input"
|
||||
("i" "Input" reverso--transient-input-infix)]
|
||||
["Parameters"
|
||||
(reverso--transient-grammar-language)]
|
||||
["Actions"
|
||||
(reverso--grammar-exec-suffix)
|
||||
("q" "Quit" transient-quit-one)])
|
||||
|
||||
(transient-define-prefix reverso ()
|
||||
"Translation, grammar checking and bilingual concordances and more."
|
||||
["Commands"
|
||||
("t" "Translation" reverso-translate)
|
||||
("c" "Context" reverso-context)
|
||||
("s" "Synomyms" reverso-synonyms)
|
||||
("g" "Grammar check" reverso-grammar)]
|
||||
["Actions"
|
||||
("q" "Quit" transient-quit-one)
|
||||
("k" "Kek" (lambda () (interactive)
|
||||
(message "%s"
|
||||
(cl-mapcan (lambda (obj)
|
||||
(when (and (slot-exists-p obj 'scope)
|
||||
(oref obj scope))
|
||||
(oref obj scope)))
|
||||
(transient-suffixes 'reverso)))))]
|
||||
(interactive)
|
||||
(setq-local reverso--use-buffer-as-input (equal current-prefix-arg '(4)))
|
||||
(transient-setup 'reverso))
|
||||
|
||||
(provide 'reverso)
|
||||
;;; reverso.el ends here
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue