blechmusikの日記

キー・カスタマイズ・ソフトウェア "DvorakJ" の覚え書きをはじめとして様々なことを書いています。

emacs.exe と emacsclient.exe を自動的に使い分ける AutoHotkey のスクリプトを改良した (gnupack 向け)

emacs.exe と emacsclient.exe を自動的に使い分ける AutoHotkey のスクリプトを作成した (gnupack 向け) - blechmusik2の日記の続きである。
emacsの諸々のパスを GUI で設定できるようにした。また、エラー通知のメッセージダイアログを少々わかりやすくした。


以下のautohotkeyのスクリプトをexe化したので配布しよう。


GUIの設定画面はつぎのとおりである。


GUIの設定ツールのソースは以下の通りだ。

;; -*-mode: ahk; coding:utf-8-with-signature-dos-*-"
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance force

;; utf-8
FileEncoding, CP65001
;; ================================================================

ini_file := "emacs_file_paths.ini"

path_gnupack_dir := ""
path_emacs_dir := ""

path_original_emacs_exe := ""
path_server_file := ""
path_emacs_exe := ""
path_emacsclientw := ""


if(FileExist(ini_file)) {
	;; ini から各種実行ファイルのパスを読み取る
	IniRead, path_emacsclientw, %ini_file%, emacs_path, path_emacsclientw
	IniRead, path_emacs_exe, %ini_file%, emacs_path, path_emacs_exe
	IniRead, path_server_file, %ini_file%, emacs_path, path_server_file
}




Gui, Add, Text, x10, path of emacs.exe
Gui, Add, Edit, vpath_emacs_exe w300, %path_emacs_exe%
Gui, Add, Button, x+10 gopen_path_emacs_exe, open...

Gui, Add, Text, x10 y+20, path of emacsclientw.exe
Gui, Add, Edit, vpath_emacsclientw w300, %path_emacsclientw%
Gui, Add, Button, x+10 gopen_path_emacsclientw, open...

Gui, Add, Text, x10 y+20, path of server file
Gui, Add, Edit, vpath_server_file w300, %path_server_file%
Gui, Add, Button, x+10 gopen_path_server_file, open...


Gui, Add, Button, x140 y+20 gguess_paths, automatically guess paths (for gnupack)
Gui, Add, Button, x10 y+10 gclear_all_paths, clear all paths
Gui, Add, Button, x210 yp+0 w150 gsave_setting, save setting
Gui, Show

return

clear_all_paths:
	path_emacs_exe := ""
	path_emacsclientw := ""
	path_server_file := ""
	
	for i,var in ["path_emacs_exe", "path_emacsclientw", "path_server_file"] {
		GuiControl, Text, %var%, 
	}
return


open_path_emacs_exe:
open_path_emacsclientw:
open_path_server_file:
	GUI, Submit, NoHide
	var_name := RegExReplace(A_ThisLabel, "open_")
	FileSelectFile, new_path, 1, , , *.exe;server
	GuiControl, Text, %var_name%, %new_path%
return


guess_paths:
	;; emacs.exe が起動中かどうかを調べる
	;; 起動中ならば emacs.exe のパスを取得する
	for process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
	{
	    if ("emacs.exe" = process.Name) {
	    	process_of_emacs_exists := True
	       path_original_emacs_exe := RegExReplace(process.CommandLine, "(""|\s.+$)")
	    }
	}
	
	
	if not (process_of_emacs_exists) {
		MsgBox, the process of the Emacs is not detected.
		return
	}
	
	;; emacs.exe が起動中のときには
	;; emacsclientw.exe のパスと
	;; gnupack のインストールディレクトリ直下の emacs.exe のパス、
	;; Emacs の server file のパスを取得する
	path_emacs_dir := RegExReplace(path_original_emacs_exe, "(?!\\)[^\\]+?$")
	path_gnupack_dir := RegExReplace(path_emacs_dir, "app\\emacs\\emacs\\bin\\")
	
	
	path_emacs_exe := path_gnupack_dir . "emacs.exe"
	path_emacsclientw := path_emacs_dir . "emacsclientw.exe"
	
	path_server_file := path_gnupack_dir . "home\.emacs.d\server\server"
	
	for i,var in ["path_emacs_exe", "path_emacsclientw", "path_server_file"] {
		var_name := %var%
		GuiControl, Text, %var%, %var_name%
	}
return


save_setting:
	IniWrite, %path_emacsclientw%, %ini_file%, emacs_path, path_emacsclientw
	IniWrite, %path_emacs_exe%, %ini_file%, emacs_path, path_emacs_exe
	IniWrite, %path_server_file%, %ini_file%, emacs_path, path_server_file
	MsgBox, done.
return

emacsとemacsclientを使い分けるツールのソースはつぎのとおりである。

;; -*-mode: ahk; coding:utf-8-with-signature-dos-*-"
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance force

;; utf-8
FileEncoding, CP65001
;; ================================================================


;; 引数の内容を取得する
arg_file := get_command_argument()[1]

;; ----------------------------------------
ini_file := "emacs_file_paths.ini"

;; ini のファイルの存否を確認する
if ( not( FileExist(ini_file) )) {
	MsgBox, % "error: " . ini_file . " is not found."
	ExitApp
}

;; ----------------------------------------
;; ini から各種パスを読み取る
IniRead, path_emacsclientw, %ini_file%, emacs_path, path_emacsclientw
IniRead, path_emacs_exe, %ini_file%, emacs_path, path_emacs_exe
IniRead, path_server_file, %ini_file%, emacs_path, path_server_file


;; 各種パスの存否を確認する
for index, file in ["path_emacsclientw", "path_emacs_exe", "path_server_file"] {
	path := %file%
	if ( not( FileExist(path))) {
		MsgBox, % "error: """ . path . """ is not found.`n(" . file . ")"
		ExitApp
	}
}

;; ----------------------------------------
;; emacs.exe が起動中かどうかを調べる
;; 起動中ならば emacs.exe のパスを取得する
for process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
{
    if ("emacs.exe" = process.Name)
       process_of_emacs_exists := True
}



;; emacs が起動中のとき
if (process_of_emacs_exists) {
	if (arg_file)
		Run, %path_emacsclientw% --server-file %path_server_file% %arg_file%
	else
		WinActivate, ahk_class Emacs
	
	ExitApp
}


;; Emacs がまだ起動していないとき
if (arg_file)
	Run, %path_emacs_exe% %arg_file%
else
	Run, %path_emacs_exe%
return


;; ----------------------------------------
;; 引数の内容をまとめて取得する関数

get_command_argument(){
    global
    local arg_list := []
    
    Loop,100
    {
        if ("" != Trim(%A_Index%)){
            arg_list.insert(%A_Index%)
        }
    }
    
    return arg_list
}