はじめに
前回までで、 別フレームに表示できるようになっていました。
Processing difference regions ... と警告が出て結果がおかしい
一度実行してから Ediff セッションを終了していない(q)とか、別で Ediff 実行して Ediff セッション終了してない場合に
Processing difference regions ...
と警告が出て、 Ediff の表示もおかしくなります。
AI さんに聞いてみる
Bing Microsoft Copilot (無料のやつ) に聞くと、何をどう聞いてもこの結果出てきます... 手元では使えませんでしたorz
課金するとマトモな結果が返ってくるんだろうか…
ediff-regions-wordwise を実行中かどうかを判定する方法
ediff-regions-wordwise
は、Emacs Lispで異なるリージョンを単語単位で比較するための関数ですね。これを実行中かどうかを判定する方法については、以下のコードスニペットが役立つかもしれません。
(defun my-ediff-wordwise-active-p ()
"Check if `ediff-regions-wordwise' is currently running."
(and (boundp 'ediff-buffer-A)
(boundp 'ediff-buffer-B)
(not (null ediff-buffer-A))
(not (null ediff-buffer-B))
(eq major-mode 'ediff-mode)))
泣く泣く Ediff のソースを追う
Ediff の ドキュメント https://www.gnu.org/software/emacs/manual/html_mono/ediff.html
とか、 ソース(手元では
/usr/share/emacs/29.3/elisp/vc/ediff-*.el.gz )
を追って調べた所、見つけました。 M-x eregistry の処理を行っている一部。
defun ediff-redraw-registry-buffer 内
(前略)
(if (null ediff-session-registry)
(insert " ******* No active Ediff sessions *******\n"))
(後略)
たぶん ediff-session-registry というリストをチェックすればよいらしい。 非nil だと何かしら他で走ってる。
ということで追記箇所
;; nothing previous msgid then exit
(if (not untranslated-regions)
(error "Nothing previous msgid"))
(if (not (null ediff-session-registry)) ; ←追記
; already exist ediff session ; ←追記
(error "Please quit other Ediff session")) ; ←追記
;; source buffer for buffer-A
(save-current-buffer
(set-buffer (get-buffer-create
今の所意図通り動いていはいます。既に処理中の Ediff セッションがあればエラーメッセージを出して処理せずに終了します。
プログラム
;;; po-ediff-previous-msgid.el --- ediff previous-msgid & msgid.
;;; Author: kuma35
;;; Created: 2024/12/18
;;; Commentary:
;; In po-mode,
;; previous msgid is '#|' marked in comment.
;; msgid is soruce sentence.
;; (msgstr is translated sentence.)
;; PEPM is my generate word. PoEdiffPreviousMsgid.
;; Ediff-ing previous-msgid and msgid.
;;; Code:
(declare-function
po-extract-unquoted "po-mode" (buffer start end))
(declare-function po-find-span-of-entry "po-mode" ())
(declare-function po-get-msgid "po-mode" ())
(declare-function po-previous-untranslated-regions "po-mode" ())
(declare-function
ediff-regions-internal "ediff"
(buffer-A beg-A end-A buffer-B beg-B end-B
startup-hooks job-name word-mode setup-parameters))
(defcustom po-pepm-buf-a-name "*pepm-previous-msgid*"
"BUFFER A name for `po-ediff-previous-msgid`.
PEPM is PoEdiffPreviousMsgid."
:type 'string
:require 'po-mode
:group 'po)
(defcustom po-pepm-buf-b-name "*pepm-now-msgid*"
"BUFFER B name for `po-ediff-previous-msgid` .
PEPM is PoEdiffPreviousMsgid."
:type 'string
:require 'po-mode
:group 'po)
(defcustom po-pepm-frame-name "*pepm-frame*"
"Frame name for `po-ediff-previous-msgid` .
PEPM is PoEdiffPreviousMsgid."
:type 'string
:require 'po-mode
:group 'po)
(defun po-popm-frame-named-list (name)
"List if a frame with the given NAME exists."
(let ((frames (frame-list))
(result '())
)
(dolist (frame frames)
(when (string= (frame-parameter frame 'name) name)
(push frame result)
)
)
result
)
)
(defun po-pepm-get-frame-create (name)
"If NAME's frame is exist then return exists list.
Else is not exist then create frame by NAME."
(let ((frames (po-popm-frame-named-list name))
)
(if frames
frames
(list (make-frame
`(
(name . ,name)
(fullscreen . maximized)
)
)
)
)
)
)
(defun po-extract-previous-msgid (buffer start end)
"Delete '#|' marker and unquote text from BUFFER START END.
delete '^#| ' each line. then unquote.
return is String with property."
(require 'po-mode)
(with-temp-buffer
(insert-buffer-substring buffer start end)
(goto-char (point-min))
(while (re-search-forward "^#\\(~\\)?|[ \t]*" nil t)
(replace-match "" t t))
(po-extract-unquoted
(current-buffer) (point-min) (point-max))
)
)
(defun po-ediff-previous-msgid ()
"Ediff previous msgid (marked #| ) and msgid."
(interactive)
(require 'po-mode)
(require 'ediff)
(po-find-span-of-entry)
(let (
(oldbuf (current-buffer))
(msgid (po-get-msgid))
(untranslated-regions
(po-previous-untranslated-regions))
(beg-A) (end-A) ; BUF-A for ediff-regions-internal
(beg-B) (end-B) ; BUF-B for ediff-regions-internal
(frames ; ediff target frames
(po-pepm-get-frame-create po-pepm-frame-name))
(frame)
)
;; nothing previous msgid then exit
(if (not untranslated-regions)
(error "Nothing previous msgid"))
(if (not (null ediff-session-registry))
; already exist ediff session
(error "Please quit other Ediff session"))
;; source buffer for buffer-A
(save-current-buffer
(set-buffer (get-buffer-create
po-pepm-buf-a-name))
(setq buffer-read-only nil)
(erase-buffer)
(dolist (region untranslated-regions)
(insert (po-extract-previous-msgid
oldbuf (car region) (cdr region)))
)
(goto-char (setq beg-A (point-min)))
(push-mark (setq end-A (point-max)) t t)
(setq buffer-read-only t)
(restore-buffer-modified-p nil))
;; source buffer for buffer-B
(save-current-buffer
(set-buffer (get-buffer-create
po-pepm-buf-b-name))
(setq buffer-read-only nil)
(erase-buffer)
(insert msgid)
(goto-char (setq beg-B (point-min)))
(push-mark (setq end-B (point-max)) t t)
(setq buffer-read-only t)
(restore-buffer-modified-p nil))
;; chek frames and get a frame
(if (> (length frame) 1)
(progn
(ding)
(message "Multiple %s frames exist!"
po-pepm-frame-name)
)
)
(with-selected-frame (car frames)
;; run ediff
(ediff-regions-internal
(get-buffer po-pepm-buf-a-name) beg-A end-A
(get-buffer po-pepm-buf-b-name) beg-B end-B
nil 'ediff-regions-wordwise 'word-mode nil)
) ; end of let
)
)
(provide 'po-ediff-previous-msgid)
;;; po-ediff-previous-msgid.el ends here
今回はここまで。