From 9611655fa05924b5d377a8ba0930b70769fba3da Mon Sep 17 00:00:00 2001 From: Alexander Rosenberg Date: Tue, 4 Feb 2025 20:59:13 -0800 Subject: [PATCH] Link fcitx and emacs's input method --- init.el | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/init.el b/init.el index 3fde871..b95ba8c 100644 --- a/init.el +++ b/init.el @@ -491,6 +491,88 @@ directory. Otherwise, run `find-file' on that file." ;; mozc (require 'mozc nil t) (setq default-input-method "japanese-mozc") +(defun my/-cmdline-for-pid (pid) + "Return the command line arguments passed to PID. +PID can be a string or a number." + (butlast (string-split + (with-temp-buffer + (insert-file-contents-literally + (format "/proc/%s/cmdline" pid)) + (buffer-substring-no-properties (point-min) + (point-max))) + "\0"))) +(defun my/-current-eww-config-dir () + "Return the configuration directory for a currently running eww process." + ;; This probably only works on Linux + (catch 'found + (dolist (subdir (directory-files "/proc")) + (when (string-match-p (rx bos (+ num) eos) subdir) + (ignore-error permission-denied + (let* ((attrs (file-attributes (format "/proc/%s/exe" subdir))) + (type (file-attribute-type attrs))) + (when (and (stringp type) + (string-match-p (rx (or bos "/") "eww") type)) + (cl-maplist (lambda (tail) + (when (equal (car tail) "-c") + (throw 'found (cl-second tail)))) + (my/-cmdline-for-pid subdir))))))))) +(defun my/-set-eww-fcitx-state (enabled) + "Set the fcitx state for eww to ENABLED." + (let ((args (list "update" (format "fcitx5-state=%s" (if enabled 2 1)))) + (cfg-dir (my/-current-eww-config-dir))) + (when cfg-dir + (setq args (nconc (list "-c" cfg-dir) args))) + (apply 'call-process "eww" nil 0 nil args))) +(defun my/global-toggle-mozc (&optional no-eww) + "Toggle mozc for all buffers. +With NO-EWW, don't update eww's state." + (interactive) + (let ((default-input-method "japanese-mozc")) + (toggle-input-method nil t) + (let ((activate (or (bound-and-true-p evil-input-method) + current-input-method))) + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (if activate + (activate-input-method activate) + (deactivate-input-method) + (mozc-mode -1) + (when (boundp 'evil-input-method) + (setq-local evil-input-method nil))))) + (unless no-eww + (my/-set-eww-fcitx-state activate))) + (force-mode-line-update t))) +(keymap-global-set "C-\\" #'my/global-toggle-mozc) +(defun my/mozc-active-in-buffer-p (&optional buffer) + "Return non-nil if mozc is active in BUFFER." + (unless buffer (setq buffer (current-buffer))) + (with-current-buffer buffer + (or (equal (or (bound-and-true-p evil-input-method) current-input-method) + "japanese-mozc") + (bound-and-true-p mozc-mode)))) +(defun my/-fcitx-enabled-p () + "Return non-nil if fcitx is enabled." + (ignore-errors + (= 2 (dbus-call-method :session "org.fcitx.Fcitx5" "/controller" + "org.fcitx.Fcitx.Controller1" "State")))) +(defun my/-set-fcitx-enabled (enabled) + "If ENABLED is non-nil, enabled fcitx, otherwise disabled it." + (dbus-call-method :session "org.fcitx.Fcitx5" "/controller" + "org.fcitx.Fcitx.Controller1" + (if enabled "Activate" "Deactivate"))) +(defun my/-normalize-mozc-state () + "Normalize the mozc state between Emacs and fcitx." + (if (cl-some 'frame-focus-state (frame-list)) + (progn + (when (my/-fcitx-enabled-p) + (my/-set-fcitx-enabled nil) + (when (not (my/mozc-active-in-buffer-p)) + (my/global-toggle-mozc t)))) + (when (cl-some 'my/mozc-active-in-buffer-p (buffer-list)) + (my/global-toggle-mozc t) + (my/-set-fcitx-enabled t) + (my/-set-eww-fcitx-state t)))) +(add-function :after after-focus-change-function #'my/-normalize-mozc-state) ;; migemo (use-package migemo