Ocaml的Emacs配置

环境:Emacs 24.2、linux-kernel 3.7

    关于emacs的Ocaml配置其实有很多, 本人刚刚上手, 不想搞得太复杂, 暂时只配了这些。


    turareg可以说是必备的, 提供基本的语法高亮和repl等基本功能, 官方有个ocaml-mode, 不过很少人用, 普遍都是用turareg。

;; tuareg-mode
(setq auto-mode-alist (cons '("\\.ml\\w?" . tuareg-mode) auto-mode-alist))
(autoload 'tuareg-mode "tuareg" "Major mode for editing Caml code" t)
(autoload 'camldebug "camldebug" "Run the Caml debugger" t)


    静态强类型的语言没有动态语言灵活, 不过优点也显而易见: 能在编译时而不是运行时发现错误, 现代的开发工具能把错误的发现提前至写代码的时候。如果你喜欢边写代码边频繁地在repl里运行调试, 我觉得这个就不用配了。flymake是emacs自带的, 这里只需要配置一下。

;; flymake-ocaml
(require 'flymake)
(defun flymake-ocaml-init ()
  (flymake-simple-make-init-impl
   'flymake-create-temp-with-folder-structure nil nil
   (file-name-nondirectory buffer-file-name)
   'flymake-get-ocaml-cmdline))
(defun flymake-get-ocaml-cmdline (source base-dir)
  (list "ocaml_flycheck.pl"

;; 这里flymake需要调用一个名为"ocaml_flycheck.pl"的perl脚本。
;; 自己调整perl脚本的位置, 默认与源代码同目录。

(list source base-dir)))
(push '(".+\\.ml[yilp]?$" flymake-ocaml-init flymake-simple-java-cleanup)
      flymake-allowed-file-name-masks)
(push
 '("^\\(\.+\.ml[yilp]?\\|\.lhs\\):\\([0-9]+\\):\\([0-9]+\\):\\(.+\\)"
   1 2 3 4) flymake-err-line-patterns)

;; 如果你要flymake自动执行的话……
(add-hook
 'tuareg-mode-hook
 '(lambda ()
    (if (not (null buffer-file-name)) (flymake-mode))))



以下为ocaml_flycheck.pl的代码, 记得加上可执行权限。

#!/usr/bin/env perl
# ocaml_flycheck.pl

use strict;
use warnings;

### Please rewrite the following 2 variables 
### ($ocamlc, @ocamlc_options)

my $ocamlc = 'ocamlc';          # where is ocamlc
my @ocamlc_options  = ('-c -thread unix.cma threads.cma graphics.cma'); # e.g. ('-fglasgow-exts');
my @ocamlc_packages = ();

### the following should not been edited ###

use File::Temp qw /tempfile tempdir/;
File::Temp->safe_level( File::Temp::HIGH );

my ($source, $base_dir) = @ARGV;

my @command = ($ocamlc);

while (@ocamlc_options) {
  push(@command, shift @ocamlc_options);
}

push (@command,    $source);

while (@ocamlc_packages) {
  push(@command, '-package');
  push(@command, shift @ocamlc_packages);
}

my $dir = tempdir( CLEANUP => 1 );
my ($fh, $filename) = tempfile( DIR => $dir );

system("@command >$filename 2>&1");

open(MESSAGE, $filename);
my $column = "";
while (<MESSAGE>) {
  # example message  {File "robocupenv.ml", line 133, characters 6-10:
  if (/^File "(\S+\.ml[yilp]?)", line (\d+), characters (\d+)-(\d+):\s?(.*)/) {
    print $column;
    my $error = (<MESSAGE>);       # get the next line
    chomp $error;
    print "\n"; 
    print "$1:$2:$3:";
    $column = " [$3-$4]";
    if ($error =~ /Warning(.*)/) {
	    print "$error";
    } else {
	    print "$error ";
    }
    next;
  }
  if (/\s+(.*)/) {
    my $rest = $1;
    chomp $rest;
    print $rest;
    print " ";
    next;
  }
}

close($fh);
print "$column\n";

    

    话说ocaml社区和perl社区是有什么勾搭么, 连吉祥物都是骆驼……

你可能感兴趣的:(emacs,OCaml)