Pyim + posframe无法使用

今天按照GitHub上的实例配好了Pyim,在使用popup下一切正常,然而按照建议换成posframe弹出时却无法使用:

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  font-info(nil)
  default-font-width()
  posframe-show(" *pyim-page-tooltip-posframe-buffer*" :string "=> w | [1/2]: \n1.我 2.为 3.文 4.五 5.完 " :position 1 :min-width 35 :background-color "#333333" :foreground-color "#dcdccc" :internal-border-width 0 :internal-border-color unspecified)
  pyim-page-tooltip-show("=> w | [1/2]: \n1.我 2.为 3.文 4.五 5.完 " 1)
  pyim-page-refresh()
  pyim-entered-refresh-1()
  pyim-entered-refresh()
  pyim-self-insert-command()
  funcall-interactively(pyim-self-insert-command)
  call-interactively(pyim-self-insert-command)
  pyim-start-translation(119)
  pyim-input-method(119)

btw:pyim能否默认第一个词输入中文而不需要点石成金,在使用@smallst的配置时却在中文向英文转换上又出现了bug :thinking:

Debugger entered--Lisp error: (void-variable pyim-entered-code)
  (length pyim-entered-code)
  (= (length pyim-entered-code) 0)
  (and (not (pyim-string-match-p "\\cc" str-before-1)) (= (length pyim-entered-code) 0))
  (if (pyim-string-match-p " " str-before-1) (pyim-string-match-p "\\cc" str-before-2) (and (not (pyim-string-match-p "\\cc" str-before-1)) (= (length pyim-entered-code) 0)))
  (or (if (pyim-string-match-p " " str-before-1) (pyim-string-match-p "\\cc" str-before-2) (and (not (pyim-string-match-p "\\cc" str-before-1)) (= (length pyim-entered-code) 0))))
  (if (> (point) (save-excursion (back-to-indentation) (point))) (or (if (pyim-string-match-p " " str-before-1) (pyim-string-match-p "\\cc" str-before-2) (and (not (pyim-string-match-p "\\cc" str-before-1)) (= (length pyim-entered-code) 0)))))
  (if (string= (buffer-name) " *temp*") nil (if (> (point) (save-excursion (back-to-indentation) (point))) (or (if (pyim-string-match-p " " str-before-1) (pyim-string-match-p "\\cc" str-before-2) (and (not (pyim-string-match-p "\\cc" str-before-1)) (= (length pyim-entered-code) 0))))))
  (let ((str-before-1 (pyim-char-before-to-string 0)) (str-before-2 (pyim-char-before-to-string 1))) (if (string= (buffer-name) " *temp*") nil (if (> (point) (save-excursion (back-to-indentation) (point))) (or (if (pyim-string-match-p " " str-before-1) (pyim-string-match-p "\\cc" str-before-2) (and (not (pyim-string-match-p "\\cc" str-before-1)) (= (length pyim-entered-code) 0)))))))
  pyim-probe-dynamic-english-custom()
  #f(compiled-function (x) #<bytecode 0x2dbfae9>)(pyim-probe-dynamic-english-custom)
  cl-some(#f(compiled-function (x) #<bytecode 0x2dbfae9>) (pyim-probe-dynamic-english-custom pyim-probe-isearch-mode pyim-probe-program-mode pyim-probe-org-structure-template))
  pyim-auto-switch-english-input-p()
  pyim-input-chinese-p()
  pyim-self-insert-command()
  funcall-interactively(pyim-self-insert-command)
  call-interactively(pyim-self-insert-command)
  pyim-start-translation(112)
  pyim-input-method(112)

配置

;;; package --- custome configuration of pyim
;;; Commentary:
;;; Code:
(require 'posframe)
;;; from @smallst
(defun pyim-probe-dynamic-english-custom ()
  "Auto transition of pyim English-Chinese."
  (let ((str-before-1 (pyim-char-before-to-string 0))
        (str-before-2 (pyim-char-before-to-string 1)))
    (unless (string= (buffer-name) " *temp*")
      (if (> (point) (save-excursion (back-to-indentation)
                                     (point)))
          (or (if (pyim-string-match-p " " str-before-1)
                  (pyim-string-match-p "\\cc" str-before-2)
                (and (not (pyim-string-match-p "\\cc" str-before-1))
                     (= (length pyim-entered-code) 0))))))))
(use-package pyim
  :ensure nil
  :demand t
  :config
  ;; 激活 basedict 拼音词库,五笔用户请继续阅读 README
  (use-package pyim-basedict
    :ensure nil
    :config (pyim-basedict-enable))

  (setq default-input-method "pyim")

  ;; 我使用全拼
  (setq pyim-default-scheme 'quanpin)

  ;; 设置 pyim 探针设置,这是 pyim 高级功能设置,可以实现 *无痛* 中英文切换 :-)
  ;; 我自己使用的中英文动态切换规则是:
  ;; 1. 光标只有在注释里面时,才可以输入中文。
  ;; 2. 光标前是汉字字符时,才能输入中文。
  ;; 3. 使用 M-j 快捷键,强制将光标前的拼音字符串转换为中文。
  (setq-default pyim-english-input-switch-functions
                '(pyim-probe-dynamic-english-custom
                  pyim-probe-isearch-mode
                  pyim-probe-program-mode
                  pyim-probe-org-structure-template))

  (setq-default pyim-punctuation-half-width-functions
                '(pyim-probe-punctuation-line-beginning
                  pyim-probe-punctuation-after-punctuation))

  ;; 开启拼音搜索功能
  (pyim-isearch-mode 1)

  ;; 使用 popup-el 来绘制选词框, 如果用 emacs26, 建议设置
  ;; 为 'posframe, 速度很快并且菜单不会变形,不过需要用户
  ;; 手动安装 posframe 包。
  (setq pyim-page-tooltip 'popup)

  ;; 选词框显示5个候选词
  (setq pyim-page-length 5)

  :bind
  (("M-j" . pyim-convert-string-at-point) ;与 pyim-probe-dynamic-english 配合
   ("C-;" . pyim-delete-word-from-personal-buffer)))

;; (require 'pyim )
;; (require 'pyim-basedict)
;; (pyim-basedict-enable)
;; (setq default-input-method "pyim")
;; (setq pyim-punctuation-translate-p '(no yes auto))

;; ;; 我使用全拼
;; (setq pyim-default-scheme 'quanpin)

;; ;; 设置 pyim 探针设置,这是 pyim 高级功能设置,可以实现 *无痛* 中英文切换 :-)
;; ;; 我自己使用的中英文动态切换规则是:
;; ;; 1. 光标只有在注释里面时,才可以输入中文。
;; ;; 2. 光标前是汉字字符时,才能输入中文。
;; ;; 3. 使用 M-j 快捷键,强制将光标前的拼音字符串转换为中文。
;; (setq-default pyim-english-input-switch-functions
;;               '(pyim-probe-dynamic-english
;;                 pyim-probe-isearch-mode
;;                 pyim-probe-program-mode
;;                 pyim-probe-org-structure-template))

;; (setq-default pyim-punctuation-half-width-functions
;;               '(pyim-probe-punctuation-line-beginning
;;                 pyim-probe-punctuation-after-punctuation))

;; ;; 开启拼音搜索功能
;; (pyim-isearch-mode 1)

;; ;; 使用 popup-el 来绘制选词框, 如果用 emacs26, 建议设置
;; ;; 为 'posframe, 速度很快并且菜单不会变形,不过需要用户
;; ;; 手动安装 posframe 包。
;; (setq pyim-page-tooltip 'posframe)

;; ;; 选词框显示5个候选词
;; (setq pyim-page-length 5)

(provide 'init-pyim)
;;; init-pyim.el ends here

你是在终端使用么?

抱歉忘了提供平台了,MS Windows, GUI, Emacs 27.0.50

(posframe-show “test” :string “test”) 什么反应? 报错不?

去除探针就可以实现你的要求。。。

Invalid read syntax: "strange quote", "“"Error during redisplay: (eval utf-8-dos) signaled (void-variable utf-8-dos)
Error during redisplay: (eval utf-8-dos) signaled (void-variable utf-8-dos) [2 times]

开启debug模式后

Debugger entered--Lisp error: (invalid-read-syntax "strange quote" "“")
  read(#<buffer init-pyim.el>)
  #f(compiled-function () #<bytecode 0x2f94605>)()
  apply(#f(compiled-function () #<bytecode 0x2f94605>) nil)
  evil--preceding-sexp(#f(compiled-function () #<bytecode 0x2f94605>))
  apply(evil--preceding-sexp #f(compiled-function () #<bytecode 0x2f94605>) nil)
  pp-last-sexp()
  pp-eval-last-sexp(nil)
  (if (and (mark) (use-region-p)) (eval-region (min (point) (mark)) (max (point) (mark))) (pp-eval-last-sexp prefix))
  sanityinc/eval-last-sexp-or-region(nil)
  funcall-interactively(sanityinc/eval-last-sexp-or-region nil)
  call-interactively(sanityinc/eval-last-sexp-or-region nil nil)
  command-execute(sanityinc/eval-last-sexp-or-region)

:confused:

    (posframe-show "test" :string "test") 这个呢?

输出了nil,并没有异常抛出

pyim 没有正确安装?

从git上pull了最新的版本,仍然无法使用posframe,并且似乎抛出了同样的错误

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  font-info(nil)
  default-font-width()
  posframe-show(" *pyim-page-tooltip-posframe-buffer*" :string "=> s | [1/8]: \n1.是 2.上 3.时 4.事 5.水 " :position 312 :min-width 35 :background-color "#333333" :foreground-color "#dcdccc" :internal-border-width 0 :internal-border-color unspecified)
  (cond ((and (memq tooltip '(posframe child-frame)) (pyim-posframe-valid-p)) (posframe-show pyim-page-tooltip-posframe-buffer :string string :position position :min-width pyim-posframe-min-width :background-color (face-attribute 'pyim-page :background) :foreground-color (face-attribute 'pyim-page :foreground) :internal-border-width pyim-posframe-border-width :internal-border-color (face-attribute 'pyim-page-border :background))) ((eq tooltip 'minibuffer) (let ((max-mini-window-height (+ pyim-page-length 2))) (message string))) (t (popup-tip string :point position :margin 1)))
  (let ((frame (window-frame (selected-window))) (length (* pyim-page-length 10)) (tooltip pyim-page-tooltip)) (cond ((and (memq tooltip '(posframe child-frame)) (pyim-posframe-valid-p)) (posframe-show pyim-page-tooltip-posframe-buffer :string string :position position :min-width pyim-posframe-min-width :background-color (face-attribute 'pyim-page :background) :foreground-color (face-attribute 'pyim-page :foreground) :internal-border-width pyim-posframe-border-width :internal-border-color (face-attribute 'pyim-page-border :background))) ((eq tooltip 'minibuffer) (let ((max-mini-window-height (+ pyim-page-length 2))) (message string))) (t (popup-tip string :point position :margin 1))))
  pyim-page-tooltip-show("=> s | [1/8]: \n1.是 2.上 3.时 4.事 5.水 " 312)
  (cond ((equal (buffer-name) " *temp*") (message (pyim-page-style:exwm page-info))) (pyim-page-tooltip (pyim-page-tooltip-show (let ((func (intern (format "pyim-page-style:%S" pyim-page-style)))) (if (functionp func) (funcall func page-info) (pyim-page-style:two-lines page-info))) (overlay-start pyim-preview-overlay))) (t (message (pyim-page-style:minibuffer page-info))))
  (let ((message-log-max nil)) (cond ((equal (buffer-name) " *temp*") (message (pyim-page-style:exwm page-info))) (pyim-page-tooltip (pyim-page-tooltip-show (let ((func (intern ...))) (if (functionp func) (funcall func page-info) (pyim-page-style:two-lines page-info))) (overlay-start pyim-preview-overlay))) (t (message (pyim-page-style:minibuffer page-info)))))
  (if (eq (selected-window) (minibuffer-window)) (pyim-minibuffer-message (concat "\n" (pyim-page-style:minibuffer page-info))) (let ((message-log-max nil)) (cond ((equal (buffer-name) " *temp*") (message (pyim-page-style:exwm page-info))) (pyim-page-tooltip (pyim-page-tooltip-show (let ((func ...)) (if (functionp func) (funcall func page-info) (pyim-page-style:two-lines page-info))) (overlay-start pyim-preview-overlay))) (t (message (pyim-page-style:minibuffer page-info))))))
  (progn (if (eq (selected-window) (minibuffer-window)) (pyim-minibuffer-message (concat "\n" (pyim-page-style:minibuffer page-info))) (let ((message-log-max nil)) (cond ((equal (buffer-name) " *temp*") (message (pyim-page-style:exwm page-info))) (pyim-page-tooltip (pyim-page-tooltip-show (let (...) (if ... ... ...)) (overlay-start pyim-preview-overlay))) (t (message (pyim-page-style:minibuffer page-info)))))))
  (if (and (null unread-command-events) (null unread-post-input-method-events)) (progn (if (eq (selected-window) (minibuffer-window)) (pyim-minibuffer-message (concat "\n" (pyim-page-style:minibuffer page-info))) (let ((message-log-max nil)) (cond ((equal (buffer-name) " *temp*") (message (pyim-page-style:exwm page-info))) (pyim-page-tooltip (pyim-page-tooltip-show (let ... ...) (overlay-start pyim-preview-overlay))) (t (message (pyim-page-style:minibuffer page-info))))))))
  (let* ((end (pyim-page-end)) (start (1- (pyim-page-start))) (candidates pyim-candidates) (candidate-showed (mapcar #'(lambda (x) (if (stringp x) (replace-regexp-in-string ":" "" x) x)) (cl-subseq candidates start end))) (pos (- (min pyim-candidate-position (length candidates)) start)) (page-info (make-hash-table))) (puthash :current-page (pyim-page-current-page) page-info) (puthash :total-page (pyim-page-total-page) page-info) (puthash :candidates candidate-showed page-info) (puthash :position pos page-info) (if (and (null unread-command-events) (null unread-post-input-method-events)) (progn (if (eq (selected-window) (minibuffer-window)) (pyim-minibuffer-message (concat "\n" (pyim-page-style:minibuffer page-info))) (let ((message-log-max nil)) (cond ((equal ... " *temp*") (message ...)) (pyim-page-tooltip (pyim-page-tooltip-show ... ...)) (t (message ...))))))))
  pyim-page-refresh()
  (let* ((scheme-name (pyim-scheme-name)) pinyin-to-translate) (save-current-buffer (set-buffer (get-buffer-create pyim-entered-buffer)) (setq pinyin-to-translate (if (equal 1 (point)) (buffer-string) (buffer-substring-no-properties 1 (point))))) (setq pyim-imobjs (pyim-imobjs-create pinyin-to-translate scheme-name)) (setq pyim-candidates (or (delete-dups (pyim-candidates-create pyim-imobjs scheme-name)) (list pinyin-to-translate))) (setq pyim-candidate-position 1) (pyim-preview-refresh) (pyim-page-refresh))
  pyim-entered-refresh-1()
  (cond ((or no-delay (not pyim-exhibit-delay-ms) (eq pyim-exhibit-delay-ms 0)) (pyim-entered-refresh-1)) (t (setq pyim--exhibit-timer (run-with-timer (/ pyim-exhibit-delay-ms 1000.0) nil #'pyim-entered-refresh-1))))
  (if (= (length (pyim-entered-get)) 0) (pyim-terminate-translation) (if pyim--exhibit-timer (progn (cancel-timer pyim--exhibit-timer))) (cond ((or no-delay (not pyim-exhibit-delay-ms) (eq pyim-exhibit-delay-ms 0)) (pyim-entered-refresh-1)) (t (setq pyim--exhibit-timer (run-with-timer (/ pyim-exhibit-delay-ms 1000.0) nil #'pyim-entered-refresh-1)))))
  pyim-entered-refresh()
  (cond ((cl-some #'(lambda (x) (if (functionp x) (progn (funcall x)))) pyim-autoselector) (setq unread-command-events (cons last-command-event unread-command-events)) (if (equal pyim-candidates (list (pyim-entered-get))) nil (pyim-outcome-handle 'candidate)) (pyim-terminate-translation)) ((pyim-input-chinese-p) (save-current-buffer (set-buffer (get-buffer-create pyim-entered-buffer)) (insert (char-to-string last-command-event))) (pyim-entered-refresh)) (pyim-candidates (pyim-outcome-handle 'candidate-and-last-char) (pyim-terminate-translation)) (t (pyim-outcome-handle 'last-char) (pyim-terminate-translation)))
  pyim-self-insert-command()
  funcall-interactively(pyim-self-insert-command)
  call-interactively(pyim-self-insert-command)
  (condition-case err (call-interactively cmd) ((debug error) (message "pyim 出现错误: %S , 开启 debug-on-error 后可以了解详细情况。" err) (beep)))
  (progn (setq last-command-event (aref keyseq (1- (length keyseq))) last-command this-command this-command cmd) (setq key t) (condition-case err (call-interactively cmd) ((debug error) (message "pyim 出现错误: %S , 开启 debug-on-error 后可以了解详细情况。" err) (beep))))
  (if (if key (commandp cmd) (eq cmd 'pyim-self-insert-command)) (progn (setq last-command-event (aref keyseq (1- (length keyseq))) last-command this-command this-command cmd) (setq key t) (condition-case err (call-interactively cmd) ((debug error) (message "pyim 出现错误: %S , 开启 debug-on-error 后可以了解详细情况。" err) (beep)))) (setq unread-command-events (string-to-list (this-single-command-raw-keys))) (pyim-terminate-translation))
  (let* ((keyseq (read-key-sequence nil nil nil t)) (cmd (lookup-key pyim-mode-map keyseq))) (if (if key (commandp cmd) (eq cmd 'pyim-self-insert-command)) (progn (setq last-command-event (aref keyseq (1- (length keyseq))) last-command this-command this-command cmd) (setq key t) (condition-case err (call-interactively cmd) ((debug error) (message "pyim 出现错误: %S , 开启 debug-on-error 后可以了解详细情况。" err) (beep)))) (setq unread-command-events (string-to-list (this-single-command-raw-keys))) (pyim-terminate-translation)))
  (while pyim-translating (set-buffer-modified-p modified-p) (let* ((keyseq (read-key-sequence nil nil nil t)) (cmd (lookup-key pyim-mode-map keyseq))) (if (if key (commandp cmd) (eq cmd 'pyim-self-insert-command)) (progn (setq last-command-event (aref keyseq (1- (length keyseq))) last-command this-command this-command cmd) (setq key t) (condition-case err (call-interactively cmd) ((debug error) (message "pyim 出现错误: %S , 开启 debug-on-error 后可以了解详细情况。" err) (beep)))) (setq unread-command-events (string-to-list (this-single-command-raw-keys))) (pyim-terminate-translation))))
  (let* ((echo-keystrokes 0) (help-char nil) (overriding-terminal-local-map pyim-mode-map) (generated-events nil) (input-method-function nil) (input-method-use-echo-area nil) (modified-p (buffer-modified-p)) last-command-event last-command this-command) (setq pyim-translating t) (pyim-entered-erase-buffer) (pyim-outcome-handle "") (if key (progn (setq unread-command-events (cons key unread-command-events)))) (while pyim-translating (set-buffer-modified-p modified-p) (let* ((keyseq (read-key-sequence nil nil nil t)) (cmd (lookup-key pyim-mode-map keyseq))) (if (if key (commandp cmd) (eq cmd 'pyim-self-insert-command)) (progn (setq last-command-event (aref keyseq (1- ...)) last-command this-command this-command cmd) (setq key t) (condition-case err (call-interactively cmd) ((debug error) (message "pyim 出现错误: %S , 开启 debug-on-error 后可以了解详细情况。" err) (beep)))) (setq unread-command-events (string-to-list (this-single-command-raw-keys))) (pyim-terminate-translation)))) (pyim-magic-convert (pyim-outcome-get)))
  (if (or (integerp key) (null key)) (let* ((echo-keystrokes 0) (help-char nil) (overriding-terminal-local-map pyim-mode-map) (generated-events nil) (input-method-function nil) (input-method-use-echo-area nil) (modified-p (buffer-modified-p)) last-command-event last-command this-command) (setq pyim-translating t) (pyim-entered-erase-buffer) (pyim-outcome-handle "") (if key (progn (setq unread-command-events (cons key unread-command-events)))) (while pyim-translating (set-buffer-modified-p modified-p) (let* ((keyseq (read-key-sequence nil nil nil t)) (cmd (lookup-key pyim-mode-map keyseq))) (if (if key (commandp cmd) (eq cmd 'pyim-self-insert-command)) (progn (setq last-command-event (aref keyseq ...) last-command this-command this-command cmd) (setq key t) (condition-case err (call-interactively cmd) (... ... ...))) (setq unread-command-events (string-to-list (this-single-command-raw-keys))) (pyim-terminate-translation)))) (pyim-magic-convert (pyim-outcome-get))) (char-to-string key))
  pyim-start-translation(115)
  (let ((input-string (pyim-start-translation key))) (if (and (stringp input-string) (> (length input-string) 0)) (progn (if input-method-exit-on-first-char (list (aref input-string 0)) (mapcar 'identity input-string)))))
  (unwind-protect (let ((input-string (pyim-start-translation key))) (if (and (stringp input-string) (> (length input-string) 0)) (progn (if input-method-exit-on-first-char (list (aref input-string 0)) (mapcar 'identity input-string))))) (pyim-preview-delete-overlay) (pyim-entered-erase-buffer))
  (progn (unwind-protect (let ((input-string (pyim-start-translation key))) (if (and (stringp input-string) (> (length input-string) 0)) (progn (if input-method-exit-on-first-char (list (aref input-string 0)) (mapcar 'identity input-string))))) (pyim-preview-delete-overlay) (pyim-entered-erase-buffer)))
  (unwind-protect (progn (unwind-protect (let ((input-string (pyim-start-translation key))) (if (and (stringp input-string) (> (length input-string) 0)) (progn (if input-method-exit-on-first-char (list ...) (mapcar ... input-string))))) (pyim-preview-delete-overlay) (pyim-entered-erase-buffer))) (if modified nil (restore-buffer-modified-p nil)))
  (let* ((modified (buffer-modified-p)) (buffer-undo-list t) (inhibit-read-only t) (inhibit-modification-hooks t)) (unwind-protect (progn (unwind-protect (let ((input-string (pyim-start-translation key))) (if (and (stringp input-string) (> ... 0)) (progn (if input-method-exit-on-first-char ... ...)))) (pyim-preview-delete-overlay) (pyim-entered-erase-buffer))) (if modified nil (restore-buffer-modified-p nil))))
  (if (or buffer-read-only overriding-terminal-local-map overriding-local-map) (list key) (pyim-preview-setup-overlay) (let* ((modified (buffer-modified-p)) (buffer-undo-list t) (inhibit-read-only t) (inhibit-modification-hooks t)) (unwind-protect (progn (unwind-protect (let ((input-string ...)) (if (and ... ...) (progn ...))) (pyim-preview-delete-overlay) (pyim-entered-erase-buffer))) (if modified nil (restore-buffer-modified-p nil)))))
  pyim-input-method(115)
  recursive-edit()
  debug()
  funcall-interactively(debug)
  call-interactively(debug record nil)
  command-execute(debug record)
  counsel-M-x-action("debug")
  ivy-call()
  ivy-read("M-x " ("package-delete" "package-install" "eshell" "toggle-debug-on-error" "package-list-packages" "package-menu-mark-upgrades" "describe-key" "flycheck-select-checker" "describe-font" "pyim-convert-code-at-point" "flycheck-mode" "describe-mode" "pyim-dicts-manager" "toggle-input-method" "smex" "version" "pyim-start" "company-mode" "ivy-toggle-fuzzy" "evil-ex" "load-theme" "counsel-M-x" "eww-open-file" "company-anaconda" "flycheck-compile" "list-input-methods" "format-encode-buffer" "package-refresh-contents" "smex-major-mode-commands" "cd" "ri" "5x5" "arp" "dbx" "dig" "erc" "ert" "eww" "ftp" "gdb" "irc" "jdb" "man" "mpc" "pdb" "pwd" "rsh" "sdb" "vlf" "xdb" ...) :predicate #f(compiled-function (x) #<bytecode 0x5b38ce1>) :require-match t :history counsel-M-x-history :action counsel-M-x-action :keymap (keymap (67108908 . counsel--info-lookup-symbol) (67108910 . counsel-find-symbol)) :initial-input nil :caller counsel-M-x)
  counsel-M-x()
  funcall-interactively(counsel-M-x)
  call-interactively(counsel-M-x nil nil)
  command-execute(counsel-M-x)

似乎是中文字体的问题,我将原默认中文字体"微软雅黑"换掉后便可以正常工作了