ラベル Emacs Lisp の投稿を表示しています。 すべての投稿を表示
ラベル Emacs Lisp の投稿を表示しています。 すべての投稿を表示

2013-11-17

コマンドのハードコーディングを回避する仕組み

/bin/sh決め打ちとかそういうのを回避するために使う。こういうの、他の人も色々書いてる気がするけど。

(defvar alternate-program-table
  (make-hash-table :test 'equal))

(defmacro define-alternate-program (program alt)
  `(puthash ,program ,alt alternate-program-table))

(defun alternate-program (program)
  (gethash program alternate-program-table))

(defadvice start-process (around kludge-for-hard-coding (name buffer program &rest program-args) activate)
  (let* ((alternate (alternate-program program))
         (program (or (if (consp alternate) (car alternate) alternate) program))
         (program-args (if (consp alternate) (append (cdr alternate) program-args) program-args)))
    ad-do-it))

こういう感じに使う。

(defmacro when-windows (&rest body)
  `(if-windows (progn ,@body)))

(when-windows
  (define-alternate-program "/bin/sh" '("fakecygpty" "/bin/sh")))

Cygwin環境とfakecygptyがちゃんとあれば、term.elのansi-termとかがWindowsでもきちんと動作するように。

2012-09-05

OCamlのtoplevelを再起動するための設定

#quit;;してM-x tuareg-run-ocamlするのが面倒になってきたので。Emacs Lispは詳しくないから間違った作法とかがあるかも。(特にプロセスの終了を待つあたりとか)

(defun restart-ocaml-toplevel ()
  (interactive)
  (let ((buffer (get-buffer tuareg-interactive-buffer-name)))
    (cond ((null buffer) (tuareg-run-ocaml))
          (t
           (let ((process (get-buffer-process buffer)))
             (when process
               (comint-simple-send process "#quit;;")
               (with-timeout (10)
                 (while (comint-check-proc buffer)
                   (sleep-for 0 500)))))
           (goto-char (point-max))
           (tuareg-run-ocaml)))))

(defun introduce-tuareg-toplevel-restart ()
  (define-key tuareg-mode-map "\C-cr" 'restart-ocaml-toplevel))

(add-hook 'tuareg-mode-hook 'introduce-tuareg-toplevel-restart)

2012-08-25

OCamlSpotterを強引に使うための設定

CygwinでビルドしたOCaml 4.00.0と、それを使ってビルドしたOCamlSpotter(bf0060bc031f)と、non-Cygwin Emacs 23.2を併用するためのkluge。CygwinでのパスとWindowsのパスの表現の違いによる問題を解決するものなので、MinGW版のOCamlならこういう設定は不要のはず。多分素直に使える。

.emacsの(require 'ocamlspot)以降に

(defun cygpath (args)
  (let* ((command (with-output-to-string
                    (princ "cygpath")
                    (mapc (lambda (x) (princ " ") (princ x)) args)))
         (result (shell-command-to-string command)))
    (replace-regexp-in-string "\n$" "" result)))

(defun ocamlspot-query-string-at-cursor ()
  (let ((file-name (cygpath `(-u ,(prin1-to-string (buffer-file-name))))))
    (setq ad-return-value
          (format "%s:l%dc%d"
                  file-name
                  (ocamlspot-lines-of-point)
                  (ocamlspot-bytes-of-line-to-point)))))

(defun ocamlspot-find-file-existing (path)
  (let ((path (cygpath `(-w ,path))))
    (if (file-exists-p path)
        (find-file-other-window path)
      (ocamlspot-message-add (format "ERROR: source file %s was not found" path))
      nil)))

で取り敢えず動くと思う。良く分からなかったりちゃんと動かなかったら諦めた方が吉。

やってて思ったけど、素直に仮想マシンにLinuxなりをインストールした方が苦労が少なそう。でもこのPCメモリそんな積んでないから厳しい。

2012-08-17

Caml modeの設定

Caml modeの設定も。

(autoload 'caml-mode "caml" "Major mode for editing OCaml code." t)
(autoload 'run-caml "inf-caml" "Run an inferior OCaml process." t)
(autoload 'camldebug "camldebug" "Run ocamldebug on program." t)

(setq inferior-caml-program
      (if-windows "sh -c ocaml" "ocaml")
      auto-mode-alist
      (cons '("\\.ml[iylp]?$" . caml-mode) auto-mode-alist)
      interpreter-mode-alist
      `(("ocamlrun" . caml-mode)
        ("ocaml" . caml-mode)
        ,@interpreter-mode-alist)
      process-coding-system-alist
      (cons (if-windows '("^sh$" utf-8 . utf-8)
                        '("ocaml" utf-8 . utf-8))
            process-coding-system-alist))

;; If "ocamlc -where" is called, OCaml built with Cygwin returns a Cygwin-style
;; path. Caml mode on non-Cygwin Emacs can't handle it.
(when-windows
  (setq ocaml-lib-path '("C:/Cygwin/usr/local/ocaml-4.00.0/lib/ocaml")))

(add-hook 'caml-mode-hook 'viper-mode)

(if window-system
    (require 'caml-font))

inferior-caml-program"sh -c ocaml"にしているのは、OCamlのインストール先の都合上。/usr/local/ocaml-4.00.0以下にインストールして、/usr/local/binなどに各ファイルのシンボリックリンクを張っているんだけど、CygwinをリンクしてないEmacsだとシンボリックリンクを辿れないし、パスを追加したりとかは色々面倒なので。

shのprocess coding systemをここで指定しているのは格好悪いかも。どうせCygwinは1.7以降UTF-8前提なんだし、別の所で堂々と設定したほうが良いかもしれない。

Tuareg modeの設定

現時点での設定。

(load "tuareg-site-file")

(setq tuareg-use-smie t
      tuareg-interactive-program inferior-caml-program
      tuareg-browser 'browse-url-firefox
      tuareg-library-path
      (if-windows "C:/Cygwin/usr/local/ocaml-4.00.0/lib/ocaml/"
                  "/usr/local/lib/ocaml/"))

(defun customize-tuareg-face ()
  (set-face-attribute 'tuareg-font-lock-governing-face nil
                      :foreground (face-attribute 'font-lock-keyword-face :foreground)
                      :weight 'normal)
  (set-face-attribute 'tuareg-font-lock-operator-face nil
                      :foreground "#999999"))

(defun set-tuareg-compile-command ()
  (set (make-local-variable 'compile-command) "omake"))

(when window-system
  (add-hook 'tuareg-mode-hook 'customize-tuareg-face))

(add-hook 'tuareg-mode-hook 'set-tuareg-compile-command)
(add-hook 'tuareg-mode-hook 'viper-mode)

ちなみに、if-windows

(defmacro if-windows (then &optional else)
  `(if (eq window-system 'w32)
       ,then ,else))

こういうマクロ。