【技巧分享】 Emacs+macOS 最简单也最强大的中英互译设置,不只英语

哈哈哈,我太兴奋了,以至于必须再单独发一帖。

首先是在 Keyboard Maestro 实现了一个 macro 按两次 Option+T 将外语翻译为中文,或将中文翻译为英文。

Emacs 必须不能落后!

功能

按两次 H-t,如果光标所在段落中没有中文字符,将段落翻译为中文,如果段落中有中文字符,将段落翻译为英文。

使用临时文件和系统剪切板作为数据交换。

不只是中英互译哦,个人笔记不方便展示,就用 KM 展示一下能力吧:

依赖

下载并安装两个快捷指令:Translate File 和 Translate File 2 English

Emacs 设置

;; Siri Shortcuts: Translate
;; {{{
(add-to-list 'display-buffer-alist
             (cons
              "\\*Async Shell Command\\*.*"
              (cons #'display-buffer-no-window nil)))

(defun my/siri-translate ()
  (interactive)
  (let
      ((tempfile
        (make-temp-file "siri-translate-" nil ".txt")
        ))
    (write-region
     (format "%s" (thing-at-point 'paragraph))
     nil
     tempfile)
    (end-of-paragraph-text)             ; jump to end of paragraph
    (shell-command (format "shortcuts run \"Translate File\" -i %s &" tempfile))
    )
  (shell-command "open -b org.gnu.Emacs")
  )

;; (keymap-global-set "C-c C-t" #'my/siri-translate)

(defun my/siri-translate2english ()
  (interactive)
  (let
      ((tempfile
        (make-temp-file "siri-translate-" nil ".txt")
        ))
    (write-region
     (format "%s" (thing-at-point 'paragraph))
     nil
     tempfile)
    (end-of-paragraph-text)             ; jump to end of paragraph
    (shell-command (format "shortcuts run \"Translate File 2 English\" -i %s &" tempfile))
    )
  (shell-command "open -b org.gnu.Emacs")
  )

;; (keymap-global-set "C-c C-e" #'my/siri-translate2english)

(defun language-to-zh-or-zh-to-english ()
  (interactive) ;; 测试
  (let ((string (thing-at-point 'paragraph)))
    (if (eq (string-match "\\cC" string) nil)
        (my/siri-translate)
      (my/siri-translate2english)
      )
    )
  )

(keymap-global-set "H-t H-t" #'language-to-zh-or-zh-to-english)
;; }}}

效果

这是 Emacs scratch buffer

;; This buffer is for text that is not saved, and for Lisp evaluation.
;; To create a file, visit it with <open> and enter text in its buffer.

按两下 H-t 得到

;;此缓冲区用于未保存的文本和Lisp评估。;;要创建文件,请使用<open>访问它,并在其缓冲区中输入文本。

在翻译后的文本上再按两下 H-t 得到

;;This buffer is used for unsaved text and Lisp evaluation. ;;To create a file, please use <open> to access it and enter text in its buffer.

碎碎念

我的 H 是设置为了右 Command

(setq mac-right-command-modifier 'hyper )

写 elisp 真舒服啊,就像在造一棵树,把枝桠安排好就自动长好了。

Sexp is so sexy!

Keyboard Maestro 和 Alfred Workflow 我用了几年还是一知半解很少自己动手写,Emacs Lisp 让我体会到了当年 RMS 忽悠办公室文员说写 elisp 不算编程的话好像也不是很不可思议。我真的一个 elisp 教程都没看下去,大部分时间是看别人的代码和查 Emacs 内的文档。

离线使用

如果打开了 macOS 的【系统设置-通用-语言和地区-翻译语言…-设备端模式】就可以离线使用了。

3 个赞

如果你也是 Keyboard Maestro 用户,KM macro 在这里:

可以去 KM 论坛围观

和 Emacs 版略有不同的是,KM 翻译的是选中的文本或者剪贴板内容。

依赖是一样的,都需要安装上述的两个快捷指令。

如果里面有一些 latex 的命令呢?

这就有点为难俺胖虎了(虽然我并不胖

在知乎现找了 LaTeX 试了一下,果然不太适合。

我在 Emacs 里设置的是翻译光标下的段落,在快捷指令里设置的是把换行符都替换为空格(避免翻译断句问题),虽然 prog-mode 下也能用,但这样用也太奇怪了。

\documentclass[12pt, a4paper, oneside]{ctexart}

\begin{document}

这里是正文. 

\end{document}
\Documentclass[12pt, a4paper, oneside]{ctexart} \begin{document} This is the text. \end{document}

等我有能力了再改成翻译选区或段落。

稍微修改了一下,支持在 echo area 显示翻译结果。

配置用 use-package 包起来是为了看着方便,绑定的快捷键能显示在 describe-personal-keybindings 里。

(use-package simple
 :ensure nil
 :bind ("H-t H-t" . my/translate-language-to-zh-or-zh-to-english)
 :config
 ;; Siri Shortcuts: Translate
 (defun my/siri-translate ()
   (interactive)
   (let ((tempfile (make-temp-file "siri-translate-" nil ".txt")))
     (write-region (format "%s" (thing-at-point 'paragraph)) nil tempfile)
     (end-of-paragraph-text) ; jump to end of paragraph
     (shell-command (format "shortcuts run \"Translate File\" -i %s" tempfile)))
   (shell-command "open -b org.gnu.Emacs")
   ;; (shell-command "pbpaste")
   )

 (defun my/siri-translate2english ()
   (interactive)
   (let ((tempfile (make-temp-file "siri-translate-" nil ".txt")))
     (write-region (format "%s" (thing-at-point 'paragraph)) nil tempfile)
     (end-of-paragraph-text) ; jump to end of paragraph
     (shell-command
      (format "shortcuts run \"Translate File 2 English\" -i %s" tempfile)))
   (shell-command "open -b org.gnu.Emacs")
   ;; (shell-command "pbpaste")
   )

 (defun my/translate-language-to-zh-or-zh-to-english ()
   (interactive) ; 测试
   (let ((string (thing-at-point 'paragraph)))
     (if (eq (string-match "\\cC" string) nil)
         (my/siri-translate)
       (my/siri-translate2english)))
   (shell-command "pbpaste")))

BONUS

如果你需要 OCR: