;;; mozc-posframe.el --- Allow mozc.el candidates to be shown in a posframe -*- lexical-binding: t -*- ;;; Commentary: ;;; Code: (require 'mozc) (require 'posframe) ;; Show candidates in a posframe (defconst my/-mozc-cand-posframe-name " *mozc-posframe*") (defun my/-mozc-cand-posframe-live-p () "Return non-nil if the posframe of mozc-posframe is live." (buffer-live-p (get-buffer my/-mozc-cand-posframe-name))) (defun my/-mozc-cand-posframe-clean-up () "Clean up the current candidate session." (my/-mozc-cand-posframe-clear)) (defun my/-mozc-cand-posframe-clear () "Clear the candidate window." (when (my/-mozc-cand-posframe-live-p) (posframe-delete my/-mozc-cand-posframe-name))) (defun my/-mozc-cand-posframe-update (candidates) "Update the candidate window using posframes. CANDIDATES is the list of candidates." (let ((contents (mozc-cand-overlay-make-contents candidates)) (position (posn-point mozc-preedit-posn-origin)) space-idxs right-sizes) (with-current-buffer (get-buffer-create my/-mozc-cand-posframe-name) (erase-buffer) (cl-loop for (left right face) in contents do (let ((start (point))) (when left (insert left)) (push (point) space-idxs) (insert " ") (if right (let ((right-start (point))) (insert right) (with-restriction right-start (point) (push (car (buffer-text-pixel-size)) right-sizes))) (push 0 right-sizes)) (put-text-property start (point) 'face face) (insert "\n"))) (let ((width (car (buffer-text-pixel-size)))) (message "%s" width) (cl-loop for pos in space-idxs for right-width in right-sizes do (message "%s" (- width right-width)) do (put-text-property pos (1+ pos) 'display `(space :align-to (,(- width right-width)))))) (posframe-show (current-buffer) :position position)))) (add-to-list 'mozc-candidate-dispatch-table '(posframe (clean-up . my/-mozc-cand-posframe-clean-up) (clear . my/-mozc-cand-posframe-clear) (update . my/-mozc-cand-posframe-update))) (provide 'mozc-posframe) ;;; mozc-posframe.el ends here