新写的 Google 翻译插件

MELPA 里的翻译插件试了一下,都不够舒服,所以自己写了一个。

使用 Google 进行翻译,在国内可以流畅使用。

地址: https://github.com/lorniu/go-translate

文档: https://github.com/lorniu/go-translate/blob/master/README-zh.md

有需要的可以看看。

8赞

异步,好评。

我有计划写一个从 web 获取翻译的版本。

怎么个 web 法?愿闻其详。

正在找合适的翻译插件,立刻试了下,出错了: go-translate-token--extract-tkk: Search failed: ",tkk:'\\([0-9]+\\)\\.\\([0-9]+\\)"

我用了很多天没见过这样的问题。

  • 请确定已将地址设置为 http://translate.google.cn
  • 另外,尝试从网页上看看这个网址是否能够访问
  • 请提供 Emacs 的版本信息

在国内,有时候会因为网络问题出现一些莫名其妙的状况。我不知道其他地方有没有对 Google 翻译进行访问限制。感谢多尝试几次,帮忙定位一下问题的原因我好更正。

环境win10+msys2, emacs master-branch emacs 配置的sock 代理。

不管是设置为 谷歌中国 还是谷歌国际,http or https 均出现这个failure。

translate.google.cn 在国内貌似是不需要代理的。你在浏览器里访问试试看。

是的,走代理和不走代理,浏览器可以都访问 translate.google.cn. 但emacs依然会出错:

go-translate-token--extract-tkk: Search failed: ",tkk:'\\([0-9]+\\)\\.\\([0-9]+\\)"
error in process sentinel: socks-send-command: SOCKS: General SOCKS server failure
error in process sentinel: SOCKS: General SOCKS server failure

我把emacs 代理设置关掉,可以显示翻译结果了。应该是和代理设置不兼容。

可能是你设置错误吧。我设置完代理,是可以正常访问的,包括 translate.google.com.

(setq url-proxy-services
      '(("http"     . "127.0.0.1:1081")
        ("https"    . "127.0.0.1:1081"))) ;; 我本地的 http 代理端口是 1081

代理设置:

;;http proxy
(setq url-proxy-services
      '(("no_proxy" . "^\\(localhost\\|10\\..*\\|192\\.168\\..*\\)")
        ("http" . "127.0.0.1:1081")
        ("https" . "127.0.0.1:1081")))

go-translate:

  (use-package go-translate
    :straight (:host github :repo "lorniu/go-translate")
    :commands (go-translate go-translate-popup)
    :config
    (setq go-translate-base-url "http://translate.google.cn")
    (setq go-translate-local-language "zh-CN")
    ;; (setq go-translate-buffer-folow-p t)
    )

写的很好啊,牛逼

很好用,目前的翻译方法能分成多个吗,比如执行的时候直接翻译,不用按回车,有编辑选中内容需求的用你现在的这个方法,在加一个直接翻译的方法,还有翻译后焦点在原buffer,还是翻译buffer也可以做成两个方法,不过这个是小问题,给个配置项也行,主要还是希望能有直接翻译的方法

@lorniu 给大佬点个赞,很好用。提2点建议:

  1. 增加一个类似go-translate-popup-current 的方法go-translate-current 直接将当前光标下的单词或者选择的内容翻译到buffer中。楼上也提到这点。因为大部分是不需要对选择的内容进行编辑,需要编辑的话,还可以取消后,直接编辑原文。如果光标下没有单词则提示用户输入。
  1. go-translate-kill-ring-save 也增加一个不提示输入的选项,只有当前光标下没内容时再提示用户输入. 这个功能我觉得在翻译的时候非常有用,基本都是翻译好,粘贴到当前buffer直接修改。

@toure00, 关于焦点的问题,其实已经有了,可以通过下面的配置,使得翻译后光标仍然在当前buffer,但是我觉得跟随更好,看完直接q就结束了。

(setq go-translate-buffer-follow-p nil)

更新: 可以自己在配置中定一个go-translate-current

(defun go-translate-current ()
  "Translate the content under cursor: selection or word.
Auto judge the direction, if failed then take the default local/target
as the direction.

This will not prompt anything."
  (interactive)
  (let ((go-translate-inputs-function #'go-translate-noprompt-inputs))
    (call-interactively #'go-translate)))

不过目前的go-translate功能在当前光标下没单词时,是报错的,建议修改为让用户输入,像go-translate-current一样就好了。

@toure00 就像 @aqua0210 说的,可以通过自定义命令的方式定制自己的翻译方式,因为每个人的需求不一样,很难通过配置参数的方式满足所有需求。

比如,如果想跳过 prompt 直接翻译,命令如下:

(defun go-translate-yours1 ()
  (interactive)
  (let ((go-translate-inputs-function #'go-translate-inputs-noprompt))
    (call-interactively #'go-translate)))

如果想跳过 prompt 而且还要窗口跟随:

(defun go-translate-yours2 ()
  (interactive)
  (let ((go-translate-buffer-follow-p t) ; 跟随
        (go-translate-inputs-function #'go-translate-inputs-noprompt))
    (call-interactively #'go-translate)))

其他的命令定制道理相同。这样虽然配置麻烦了点儿,但能尽可能保证使用的灵活。

@aqua0210 你的意思是 go-translate-noprompt-inputs 中,如果当前有选中内容或当前鼠标下有单词则直接翻译,否则弹出 minibuffer 让用户输入再翻译吗?看起来是不错的建议。go-translate-current 这样的方式我用的少,所以如果大家觉得这样更合适,我就改一下。

是的,就和当前的go-translate-popup-current一样,在没有找到输入的时候就是提示用户输入的。 还有go-translate-kill-ring-save 也加一个类似这样的,不需求提示输入的就好了。

我提交了代码,除了默认的获取用户输入的方式,额外增加了两种方式 go-translate-inputs-nopromptgo-translate-inputs-current-or-prompt

用户可以根据自己的需求通过 let-binding 的方式绑定相应的输入样式。比如

(defun go-translate-raise-error-when-nothing-at-point ()
  (interactive)
  (let ((go-translate-inputs-function #'go-translate-inputs-noprompt))
    (call-interactively #'go-translate)))

(defun go-translate-continue-prompt-from-user-when-nothing-at-point ()
  (interactive)
  (let ((go-translate-inputs-function #'go-translate-inputs-current-or-prompt))
    (call-interactively #'go-translate)))

如果想将所有的命令都改成这种输入风格的话,只需要将这一句加到配置里即可:

(setq go-translate-inputs-function #'go-translate-inputs-current-or-prompt)

看来,也许这是更灵活的。

因为根据你的建议在光标处没有内容的时候要弹出 minibuffer 的话,有可能也会让某些人困扰,还是通过这种方式将选择交给使用的人吧。

PS: 实际,刚开始我只想实现一个 go-translate 命令,其他怎么去绑定怎么去拓展交给用户自己。后面想来很多人未必能做到这一些,所以简单写了其他几个命令,足够日常使用。所以这些扩展出来的命令也是仅供参考,如果不合理的话,请大家多提意见,或者提交 PR.

1赞

赞,刚更新了。这样大家怎么设置都可以了,可谓满足了各种不同需求。
对我来说,只要上面这条配置就够用了 :grin:

@lorniu 请教一个问题。有时候从pdf复制英文的时候会带有一些中文标点符号。翻译的时候会选择汉译英,但实际上我需要的是英译汉。有办法在判断翻译方案的时候忽略标点符号吗?或者强制转换为英文标点再翻译

这个没有通用的方案。不过你可以使用下面方式过滤之后再判断:

(advice-add #'go-translate-text-local-p :filter-args
            (lambda (args)
              (setf (car args)
                    (replace-regexp-in-string "。\\|," "" (car args)))
              args))