Emacs Lisp 超初心者がコマンドを作ってみる 〜 別フレーム結果表示を組み込んでみる 〜

# はじめに

なんとなく別フレームを御す事ができるようになって気がするので、ここらあたりで組み込んでみます。

指定のフレームが何故か複数ある場合は、複数の同名フレームがあると警告を出すようにします(そしてそのまま実行を続行する)。

# プログラム(追加・変更箇所

フレーム名のデフォルトを定義
````common_lisp
(defcustom po-pepm-frame-name "*pepm-frame*"
  "Frame name for `po-ediff-previous-msgid` .
PEPM is PoEdiffPreviousMsgid."
  :type 'string
  :require 'po-mode
  :group 'po)
````

指定の NAME のフレームのリスト(存在しない時は nil )を得る
````common_lisp
(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
    )
  )
````

指定の NAME の frame のリストを得る。存在しない時はフレームを1つ作成して、要素が1つだけのリストとして返す。
````common_lisp
(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)
	       )
	     )
	    )
      )
    )
  )
````

(追加箇所) 指定した名前のフレームのリストを得て、1つを超える(2つ以上)あったらメッセージを出す(が続行する)。フレームを最大化して、そのフレームで ediff を実行する。
````common_lisp
(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"))
    ;; 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
    )
  )
````

めでたく別フレームに出るようになりましたが、既に実行中の ediff を処理中に再度実行すると Processing difference regions ... と怒られます。

次回以降でなんとかしたい。

# フレーム初期表示ディスプレイについて
なお、 手元の環境はメイン・サブ 2ディスプレイ構成なので、フレーム表示時に別ディスプレイを選択するようにすれば、サブ・ディスプレイにフレームを表示することも可能ですが、3画面以上の環境だと何処に出せばよいかはわからないのでやっていません。

一度フレームが表示したあと、ユーザー自身で好きなディスプレイに移動させれば、2回目以降の実行ではそちらへ表示が行われますので、お手数ですが1回目だけ手動で移動してください。


今回はここまで。