後日追記
emacs.exe と emacsclient.exe を自動的に使い分ける AutoHotkey のスクリプトを改良した (gnupack 向け) - blechmusik2の日記を公開した。
Emacs.exe が既に起動していたら emacsclient.exe (EmacsWiki: Emacs Client)で、そうでなければ emacs.exe (gnupack用)でファイルを開くスクリプトを作った。ただし、ここでいう emacs.exe とは emacsclientw.exeと同一のフォルダ以外に入っている emacs.exe のことではなく、 gnupack の配布パッケージにおいて特別に配布されているものだ(gnupackのインストールディレクトリ直下のemacs.exe)。emacs.exe が起動していないときに emacsclientw.exe を起動したり emacsclientw.exeを単独で起動するとエラーになるのだが、そういうエラーをAutoHotkeyのスクリプトによって抑制できるようになる。これによって、emacs.exe が起動中か否かに注意を払わなくてよくなるから、ファイルの編集作業が大分快適になるだろう。
具体的には以下の表のとおり動作する。
編集対象のファイルが渡された場合 | そうでないとき | |
---|---|---|
emacs.exeが起動中 | emacsclientw.exeでファイルを開く | emacs.exeにフォーカスを移す |
emacs.exeは未起動 | gnupackのインストールディレクトリ直下のemacs.exeを使ってファイルを開く | gnupackのインストールディレクトリ直下のemacs.exeを起動 |
ソースは以下の通りだ。スクリプトと同じフォルダに"emacs_file_paths.ini"を置き、各種実行ファイルへのパスを記述しておくこと。
;; 引数の内容を取得する arg_file := get_command_argument()[1] ;; ---------------------------------------- ini_file := "emacs_file_paths.ini" ;; ini のファイルの存否を確認する if ( not( FileExist(ini_file) )) { MsgBox, % "ini file is not found." ExitApp } ;; ---------------------------------------- ;; ini から各種実行ファイルのパスを読み取る IniRead, emacs_exe_path, %ini_file%, emacs_path, emacs_exe_path IniRead, emacsclientw_path, %ini_file%, emacs_path, emacsclientw_path IniRead, gnupack_emacs_exe_path, %ini_file%, emacs_path, gnupack_emacs_exe_path IniRead, server_file_path, %ini_file%, emacs_path, server_file_path ;; 各種実行ファイルのパスの存否を確認する for index, file in [emacs_exe_path, emacsclientw_path, gnupack_emacs_exe_path] { if ( not( FileExist(file))) { MsgBox, % "the file is not found.`n" . file } } ;; ---------------------------------------- ;; 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, %emacsclientw_path% --server-file %server_file_path% %arg_file% else WinActivate, ahk_class Emacs ExitApp } ;; Emacs がまだ起動していないとき if (arg_file) Run, %gnupack_emacs_exe_path% %arg_file% else Run, %gnupack_emacs_exe_path% return ;; ---------------------------------------- ;; 引数の内容をまとめて取得する関数 get_command_argument(){ global local arg_list := [] Loop,100 { if ("" != Trim(%A_Index%)){ arg_list.insert(%A_Index%) } } return arg_list }
また、gnupackのemacsを使用している人向けに、emacs_file_paths.iniに各種パスの設定を自動的に書き出すスクリプトを作っておいた。gnupackの初期設定が維持されているならば、正常に動作するだろう。
ini_file := "emacs_file_paths.ini" MsgBox, 4, , gnupack に収録されている Emacs の設定を`n%ini_file% に書き出しますか? IfMsgBox, No ExitApp gnupack_dir_path := "" emacs_dir_path := "" gnupack_emacs_exe_path := "" server_file_path := "" emacs_exe_path := "" emacsclientw_path := "" ;; 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_exe_path := RegExReplace(process.CommandLine, "(""|\s.+$)") } } if not (process_of_emacs_exists) { ExitApp } ;; emacs.exe が起動中のときには ;; emacsclientw.exe のパスと ;; gnupack のインストールディレクトリ直下の emacs.exe のパス、 ;; Emacs の server file のパスを取得する emacs_dir_path := RegExReplace(emacs_exe_path, "(?!\\)[^\\]+?$") gnupack_dir_path := RegExReplace(emacs_dir_path, "app\\emacs\\emacs\\bin\\") gnupack_emacs_exe_path := gnupack_dir_path . "emacs.exe" emacsclientw_path := emacs_dir_path . "emacsclientw.exe" IniWrite, %emacs_exe_path%, %ini_file%, emacs_path, emacs_exe_path IniWrite, %emacsclientw_path%, %ini_file%, emacs_path, emacsclientw_path IniWrite, %gnupack_emacs_exe_path%, %ini_file%, emacs_path, gnupack_emacs_exe_path server_file_path := gnupack_dir_path . "home\.emacs.d\server\server" IniWrite, %server_file_path%, %ini_file%, emacs_path, server_file_path