re: fastri-server が起動しているか気にしたくない

Cygwin Emacs 上でも動くように修正しました。

問題は以下の通り。

  • Cygwin の ps は uxww しても各プロセスの引数が表示されないため、fastri-server が起動しているか判定できない
  • そのため、無限に fastri-server を起動してしまう

そこで尊敬する Windows スペシャリストの真雪(id:mayuki)さんにご教示願いましたところ、すぐに「wmic process が使えるます」と答えてくださいました。

WMIとwmicコマンドを使ってシステムを管理する(基本編) − @IT によると、wmic は XP 以降の Windows に含まれているそうです。

現在のコードは以下の通りです。Cygwin, Darwin(Mac OS X), GNU/Linux 上で正しく動作する事を確認しました。Meadow は最近使っていないのですが、恐らく動くのではないかと……。

なお、

  • locate-executable は実行ファイルが存在すればそのパスを、存在しなければ nil を返す自作関数です

(when (and
       (locate-executable "fastri-server")
       (locate-executable "fri")
       (setq ri-ruby-script (locate-executable "ri-emacs"))
       (load "ri-ruby" 'noerror))

  (defun fastri-server-alive-p ()
    (with-temp-buffer
      (let
          ((progname "fastri-server")
           (wmic-tmp-file "TempWmicBatchFile.bat"))
        (cond
         (windows-p
          (call-process "wmic" nil t t "process")
          (when (file-exists-p wmic-tmp-file)
            (delete-file wmic-tmp-file)))
         (t
          (call-process "ps" nil t t "uxww")))
        (goto-char (point-min))
        (not (not (re-search-forward progname nil t))))))

  (defun fastri-server-start ()
    (unless (fastri-server-alive-p)
      (message "starting fastri-server. please wait...")
      (let*
          ((progname "fastri-server")
           (buffname (format "*%s*" progname)))

        (start-process progname buffname progname)
        (while (not
                (with-temp-buffer
                  (sit-for 0.5)
                  (call-process
                   "fri" nil t t "Kernel#lambda")
                  (goto-char (point-min))
                  (re-search-forward "lambda" nil t)))))))

  (defadvice ri-ruby-get-process (before ri/force-start-fastri-server
                                         activate)
    (fastri-server-start)))

*1:Emacs 22 では実装も同じでした……。