branch: externals/pyim commit 921e72f6440ed1554f4ca0a1742b3f2c4cc11334 Author: Feng Shu <tuma...@163.com> Commit: Feng Shu <tuma...@163.com>
Revert "Revert "添加简单的云输入法功能,参考 fcitx5."" This reverts commit 5eb65e0c84e17944633fedbd47bc74d276081f33. --- Development.org | 6 ++-- README.org | 10 ++++++ pyim-candidates.el | 9 ++++++ pyim-cloudim.el | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++ pyim.el | 3 ++ tests/pyim-tests.el | 56 +++++++++++++++++++++++++++++++++ 6 files changed, 171 insertions(+), 3 deletions(-) diff --git a/Development.org b/Development.org index 70fc29976f..db86cdfd3d 100644 --- a/Development.org +++ b/Development.org @@ -34,9 +34,9 @@ | | | | | | | | +---------------------------------------------+ | | | | | | -| | PYIM 持久化层: 探针: | | -| | -------------- ------------ | | -| | Dregcache Probe | | +| | PYIM 持久化层: 云输入法: 探针: | | +| | -------------- --------- ------------ | | +| | Dregcache Cloudim Probe | | | | Dhashcache | | | | Dict | | | +---------------------------------------------------------------------------------+ | diff --git a/README.org b/README.org index 4684ec4d92..50ad30fec3 100644 --- a/README.org +++ b/README.org @@ -101,6 +101,9 @@ pyim 的目标是: *尽最大的努力成为一个好用的 Emacs 中文输入 ;; (pyim-default-scheme 'wubi) ;; (pyim-default-scheme 'cangjie) +;; 我使用云拼音 +;; (setq pyim-cloudim 'baidu) + ;; pyim 探针设置 ;; 设置 pyim 探针设置,这是 pyim 高级功能设置,可以实现 *无痛* 中英文切换 :-) ;; 我自己使用的中英文动态切换规则是: @@ -159,6 +162,13 @@ pyim 默认使用 pyim-basedict 词库, 这个词库的词条量8万左右,是 | C-DEL 或 C-BACKSPACE | 删除最后一个拼音 | | M-DEL 或 M-BACKSPACE | 删除最后一个拼音 | | F1,F2,F3,F4 | 以词定字 | +** 使用云拼音 +pyim 可以使用搜索引擎提供的云拼音服务,比如: + +#+begin_example +(setq pyim-cloudim 'baidu) +;; (setq pyim-cloudim 'google) +#+end_example ** 使用双拼模式 pyim 支持双拼输入模式,用户可以通过变量 `pyim-default-scheme' 来设定: diff --git a/pyim-candidates.el b/pyim-candidates.el index 7311afd0cd..2a17d1d275 100644 --- a/pyim-candidates.el +++ b/pyim-candidates.el @@ -52,6 +52,9 @@ 细节信息请参考 `pyim-page-refresh' 的 docstring.") +(defvar pyim-candidates-cloud-search-function nil + "`pyim-candidates-cloud-search' 调用的函数.") + (pyim-register-local-variables '(pyim-candidates pyim-candidate-position)) @@ -155,6 +158,7 @@ IMOBJS 获得候选词条。" pyim-candidates ;; NOTE: 让第一个词保持不变是不是合理,有待进一步的观察。 `(,(car pyim-candidates) + ,@(pyim-candidates-cloud-search str 'pinyin) ,@(pyim-candidates-search-buffer (pyim-cregexp-build str 3 t)) ,@(cdr pyim-candidates)))) @@ -176,6 +180,11 @@ IMOBJS 获得候选词条。" (append (pyim-subconcat (nreverse output) "") candidates)))) +(defun pyim-candidates-cloud-search (string input-method) + "云搜索 STRING, 返回候选词条列表." + (ignore-errors + (funcall pyim-candidates-cloud-search-function string input-method))) + (defun pyim-candidates-search-buffer (regexp) "在当前 buffer 中使用 REGEXP 搜索词条。" (save-excursion diff --git a/pyim-cloudim.el b/pyim-cloudim.el new file mode 100644 index 0000000000..cf8d347581 --- /dev/null +++ b/pyim-cloudim.el @@ -0,0 +1,90 @@ +;;; pyim-cloudim.el --- cloud input method support for pyim. -*- lexical-binding: t; -*- + +;; * Header +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Feng Shu <tuma...@163.com> +;; Maintainer: Feng Shu <tuma...@163.com> +;; URL: https://github.com/tumashu/pyim +;; Keywords: convenience, Chinese, pinyin, input-method + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs 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: + +;;; Code: +;; * 代码 :code: +(require 'cl-lib) +(require 'url) +(require 'json) + +(defgroup pyim-cloudim nil + "Cloud input method for pyim." + :group 'pyim) + +(defcustom pyim-cloudim nil + "设置 pyim 使用的云输入法。" + :type '(choice + (const :tag "Do not use cloud input method." nil) + (const :tag "Use baidu cloud input method." baidu) + (const :tag "Use google cloud input method." google))) + +(defun pyim-cloudim (string input-method) + "使用云 INPUT-METHOD 输入法引擎搜索 STRING 获取词条列表. +云输入法由 `pyim-cloudim' 设置。" + (when (and pyim-cloudim (symbolp pyim-cloudim)) + (let ((func (intern (format "pyim-cloudim:%s" pyim-cloudim)))) + (when (functionp func) + (funcall func string input-method))))) + +(setq pyim-candidates-cloud-search-function #'pyim-cloudim) + +(defun pyim-cloudim:baidu (string input-method) + "使用 baidu 云 INPUT-METHOD 输入法引擎搜索 STRING, 获取词条列表。" + (when (equal input-method 'pinyin) + (with-current-buffer (url-retrieve-synchronously + (format "https://olime.baidu.com/py?py=%s" string) + t nil 0.5) + (pyim-cloudim-parse-baidu-buffer)))) + +(defun pyim-cloudim-parse-baidu-buffer () + "解析 `url-retrieve-synchronously' 返回的 baidu buffer." + (goto-char (point-min)) + (search-forward "\n\n" nil t) + (delete-region (point-min) (point)) + (let ((data (json-parse-buffer))) + (list (elt (elt (elt (gethash "0" data) 0) 0) 0)))) + +(defun pyim-cloudim:google (string input-method) + "使用 google 云 INPUT-METHOD 输入法引擎搜索 STRING, 获取词条列表。" + (when (eq input-method 'pinyin) + (with-current-buffer (url-retrieve-synchronously + (format "https://www.google.cn/inputtools/request?ime=pinyin&text=%s" string) + t nil 0.5) + (pyim-cloudim-parse-google-buffer)))) + +(defun pyim-cloudim-parse-google-buffer () + "解析 `url-retrieve-synchronously' 返回的 google buffer." + (goto-char (point-min)) + (search-forward "\n\n" nil t) + (delete-region (point-min) (point)) + (let ((data (json-parse-buffer))) + (list (elt (elt (elt (elt data 1) 0) 1) 0)))) + +;; * Footer +(provide 'pyim-cloudim) + +;;; pyim-cloudim.el ends here diff --git a/pyim.el b/pyim.el index 98bdeb9476..e03389ffba 100644 --- a/pyim.el +++ b/pyim.el @@ -854,6 +854,9 @@ FILE 的格式与 `pyim-dcache-export' 生成的文件格式相同, ;; ** pyim 探针 (require 'pyim-probe) +;; ** pyim 云输入法 +(require 'pyim-cloudim) + ;; ** pyim hacks (require 'pyim-hacks) diff --git a/tests/pyim-tests.el b/tests/pyim-tests.el index 88aef3541f..2d2e1a68fc 100644 --- a/tests/pyim-tests.el +++ b/tests/pyim-tests.el @@ -399,6 +399,18 @@ (should (equal (pyim-candidates-search-buffer (pyim-cregexp-build "nh" 3 t)) '("牛蛤" "你坏" "你好" "牛和" "你话"))))) +(ert-deftest pyim-tests-pyim-candidates-cloud-search () + (let ((pyim-candidates-cloud-search-function + (lambda (x y) + (list x y "b")))) + (should (equal (pyim-candidates-cloud-search "a" 'pinyin) '("a" pinyin "b")))) + + (let ((pyim-candidates-cloud-search-function nil)) + (should (not (pyim-candidates-cloud-search "a" 'pinyin)))) + + (let ((pyim-candidates-cloud-search-function "xxx")) + (should (not (pyim-candidates-cloud-search "a" 'pinyin))))) + ;; ** pyim-cstring 相关单元测试 (ert-deftest pyim-tests-pyim-cstring-partition () (should (equal (pyim-cstring-partition "你好 hello 你好") @@ -926,6 +938,50 @@ yin-xing 因行 ;; `pyim-dregcache-get' calls `pyim-pymap-py2cchar-get' before return result (should (eq (length words) 51)))) +(ert-deftest pyim-tests-pyim-cloudim () + (with-temp-buffer + (insert "HTTP/1.1 200 OK +Content-Length: 88 +Content-Type: text/plain; charset=utf-8 +Date: Sun, 08 May 2022 00:56:13 GMT + +{\"0\":[[[\"你好\",5,{\"pinyin\":\"ni'hao\",\"type\":\"IMEDICT\"}]]],\"1\":\"ni'hao\",\"result\":[null]}") + (should (equal (pyim-cloudim-parse-baidu-buffer) '("你好")))) + + (with-temp-buffer + (insert "HTTP/1.1 200 OK +Date: Sun, 08 May 2022 03:33:56 GMT +Pragma: no-cache +Expires: -1 +Cache-Control: no-cache, must-revalidate +Cross-Origin-Resource-Policy: cross-origin +Content-Type: application/json; charset=UTF-8 +X-Content-Type-Options: nosniff +Content-Disposition: attachment; filename=\"f.txt\" +Server: Google Input Server/1.0 +X-XSS-Protection: 0 +X-Frame-Options: SAMEORIGIN +Alt-Svc: h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\" +Transfer-Encoding: chunked + +[\"SUCCESS\",[[\"nihao\",[\"你好\"],[],{\"annotation\":[\"ni hao\"],\"candidate_type\":[0],\"lc\":[\"16 16\"]}]]]") + (should (equal (pyim-cloudim-parse-google-buffer) '("你好")))) + + (should (equal (pyim-cloudim:baidu "nihao" 'pinyin) '("你好"))) + (should (equal (pyim-cloudim:google "nihao" 'pinyin) '("你好"))) + + (let ((pyim-cloudim 'baidu)) + (should (equal (pyim-cloudim "nihao" 'pinyin) '("你好")))) + + (let ((pyim-cloudim 'google)) + (should (equal (pyim-cloudim "nihao" 'pinyin) '("你好")))) + + (let ((pyim-cloudim 'xxx)) + (should (not (pyim-cloudim "nihao" 'pinyin)))) + + (let ((pyim-cloudim nil)) + (should (not (pyim-cloudim "nihao" 'pinyin))))) + (ert-run-tests-batch-and-exit) ;; * Footer ;;; pyim-tests.el ends here