给google-translate加上posframe显示弹出窗口,比popup显示更好看,没有对齐问题


#1

https://gist.github.com/cnsunyour/9649123a86eab8eee33ecf884f69ebbb

不知道有没有用,我自己是是很喜欢posframe的。

本来想用chinese-word-at-point自动判断中英文的,但是发现判断效果不好,索性改为手动选择翻译方向。

抄袭了sdcv的posframe显示部分,感谢懒猫大佬。

更新:加了自动判断中英文进行翻译的方法

;; Google translate
;; 让google-translate使用posframe显示弹出窗口,比popup显示更好看,没有对齐问题
;; Let google-translate use posframe to display tooltip, better than popup,
;; no alignment problem
(require 'google-translate)

(setq google-translate-base-url
      "http://translate.google.cn/translate_a/single")
(setq google-translate-listen-url
      "http://translate.google.cn/translate_tts")
(setq google-translate-backend-method 'curl)
(setq google-translate-default-source-language "en")
(setq google-translate-default-target-language "zh-CN")

(defcustom google-translate-tooltip-name "*google-translate-posframe*"
  "The name of google translate tooltip name."
  :type 'string
  :group 'google-translate)

(defvar google-translate-tooltip-last-point 0
  "Hold last point when show tooltip, use for hide tooltip after move point.")

(defvar google-translate-tooltip-last-scroll-offset 0
  "Hold last scroll offset when show tooltip, use for hide tooltip after window scroll.")

(defun google-translate-hide-tooltip-after-move ()
  (ignore-errors
    (when (get-buffer google-translate-tooltip-name)
      (unless (and
               (equal (point) google-translate-tooltip-last-point)
               (equal (window-start) google-translate-tooltip-last-scroll-offset))
        (posframe-delete google-translate-tooltip-name)
        (kill-buffer google-translate-tooltip-name)))))

(defun google-translate-show-posframe-tooltip (text)
  "Show string on posframe buffer."
  ;; Show tooltip at point if word fetch from user cursor.
  (require 'posframe)
  (posframe-show google-translate-tooltip-name
                 :string text
                 :position (point)
                 :timeout 10
                 :internal-border-width 10)
  (add-hook 'post-command-hook 'google-translate-hide-tooltip-after-move)
  (setq google-translate-tooltip-last-point (point))
  (setq google-translate-tooltip-last-scroll-offset (window-start)))

(defun -region-or-word ()
  (if (use-region-p)
      (buffer-substring-no-properties (region-beginning) (region-end))
    (thing-at-point 'word t)))

(defun -chinese-word-p (word)
  (if (and word (string-match "\\cc" word)) t nil))

(defun -translate-request (source-language target-language text)
  (let* ((json (google-translate-request source-language
                                         target-language
                                         text)))
    (if (null json)
        (message "Nothing to translate.")
      (let* ((detailed-translation
              (google-translate-json-detailed-translation json))
             (detailed-definition
              (google-translate-json-detailed-definition json))
             (gtos
              (make-gtos
               :source-language source-language
               :target-language target-language
               :auto-detected-language (aref json 2)
               :text text
               :text-phonetic (google-translate-json-text-phonetic json)
               :translation (google-translate-json-translation json)
               :translation-phonetic (google-translate-json-translation-phonetic json)
               :detailed-translation detailed-translation
               :detailed-definition detailed-definition
               :suggestion (when (null detailed-translation)
                             (google-translate-json-suggestion json)))))
        (google-translate-posframe-output-translation gtos)))))

(defun google-translate-posframe-output-translation (gtos)
  "Output translation to the popup tooltip using `popup' package."
  (google-translate-show-posframe-tooltip
   (with-temp-buffer
     (google-translate-buffer-insert-translation gtos)
     (google-translate--trim-string
      (buffer-substring (point-min) (point-max))))))

(defun %google-translate-at-point++ (override-p reverse-p)
  (let* ((langs (google-translate-read-args override-p reverse-p))
         (source-language (car langs))
         (target-language (cadr langs))
         (bounds nil))
    (-translate-request
     source-language target-language
     (if (use-region-p)
         (buffer-substring-no-properties (region-beginning) (region-end))
       (or (and (setq bounds (bounds-of-thing-at-point 'word))
                (buffer-substring-no-properties (car bounds) (cdr bounds)))
           (error "No word at point."))))))

(defun google-translate-at-point++ (&optional override-p)
  "Translate at point and show result with posframe."
  (interactive "P")
  (%google-translate-at-point++ override-p nil))

(defun google-translate-at-point-reverse++ (&optional override-p)
  "Translate reverse at point and show result with posframe."
  (interactive "P")
  (%google-translate-at-point++ override-p t))

(defun google-translate-chinese-at-point++ (&optional override-p)
  "如果当前位置是中文,则自动调用反向进行中转英翻译,否则进行正向
英转中翻译。并在posframe提示框里显示结果。此方法只能用于点词翻译,
不能用于划词翻译,至于原因,我还没弄明白。"
  (interactive "P")
  (if (-chinese-word-p(-region-or-word))
      (%google-translate-at-point++ override-p t)
    (%google-translate-at-point++ override-p nil)))

(defun google-translate-chinese-at-point (&optional override-p)
  "如果当前位置是中文,则自动调用反向进行中转英翻译,否则进行正向
英转中翻译。并在另一个buffer里显示结果。此方法既可用于点词翻译,
也可用于划词翻译。"
  (interactive "P")
  (if (-chinese-word-p(-region-or-word))
      (%google-translate-at-point override-p t)
    (%google-translate-at-point override-p nil)))


#2

访问不了,重新给个地址


#3

建个仓库放着吧,国内访问gist有点问题。


#4

我直接把代码贴上来得了,文件里还有别的配置,这只是个代码片断


#5

喜欢用就好!!!


#6

站在巨人的肩膀就是好,只要做一点点小工作就能达到自己想要的结果:grinning: 真心感谢各位大神


#7

https://github.com/tumashu/chinese-yasdcv/blob/master/yasdcv.el 有类似的方式,你可以参考一下


#8

好的,马上看一下。好像是用pyim-cwords-at-point做的分词,是吗?


#9

嗯,不过比较简单的分词方式,可以试试


#10

明白。不过之前没用自动判断不是因为分词的问题,而是chinese-word-at-point里判断中文老是不正确。索性自己进行判断,加了两个方法,偷了个懒,还是用的google-translate自己的分词,仅仅是在调用的时候判断下是否包含中文,现在可以自动进行中英文互译了。

已更新楼顶代码。


#11

我目前使用youdao-dictionary, google-translate也可以参考使用相同的用法,打开一个buffer然后插入翻译后的内容,相比较于posframe和popup复制会更方便一些


#12

在另一个Buffer中显示翻译内容是原本都有的功能。我只是嫌popup显示的提示框总是有不对齐的问题,所以改成posframe,youdao-dictionary我也有改posframe的版本,没贴出来。