blog.anqou.net
rss
author
tags

ocamlformat を一部で無効化する

ocamlformat は OCaml のデファクトスタンダードのフォーマッターです。 ocaml-lsp などを使用して OCaml ファイルを保存するときに勝手に ocamlformat のフォーマットが入るようにしておくと、適当なインデントで式を書いても強力にフォーマットしてくれるので非常に便利です。

ただ、時々整形が強力すぎるときもあります。特に気になるのは以下のようなビットマップのリストを作るときや、コメント入りのリストを作るときです:

let bitmap =
  [
    0; 0; 0; 0; 1; 0; 0; 0;
    0; 0; 0; 1; 1; 0; 0; 0;
    0; 0; 0; 0; 1; 0; 0; 0;
    0; 0; 0; 0; 1; 0; 0; 0;
    0; 0; 0; 0; 1; 0; 0; 0;
    0; 0; 0; 0; 1; 0; 0; 0;
    0; 0; 0; 0; 1; 0; 0; 0;
    0; 0; 0; 1; 1; 1; 0; 0;
  ]
  |> List.map string_of_int |> String.concat ""

let commented_list =
  [
    0x00; (* 0x00 *)
    0x01; (* 0x01 *)
    0x02; (* 0x02 *)
    0x00; (* 0x00 *)
    0x01; (* 0x01 *)
    0x02; (* 0x02 *)
    0x00; (* 0x00 *)
    0x01; (* 0x01 *)
    0x02; (* 0x02 *)
    0x00; (* 0x00 *)
    0x01; (* 0x01 *)
    0x02; (* 0x02 *)
  ]

これらをフォーマットすると、以下のように読みにくいフォーマットになってしまいます:

let bitmap =
  [
    0;
    0;
    0;

    (* 中略 *)

    1;
    0;
    0;
  ]
  |> List.map string_of_int |> String.concat ""

let commented_list =
  [
    0x00;
    (* 0x00 *)
    0x01;
    (* 0x01 *)
    0x02;
    (* 0x02 *)

    (* 中略 *)

    0x00;
    (* 0x00 *)
    0x01;
    (* 0x01 *)
    0x02;
    (* 0x02 *)
  ]

このような意図しない整形が行われる場合 [@ocamlformat "disable"] というアノテーションを使用することで整形を無効化することができます。@ が一つなら式単位[1]での無効化、@@ ならブロック単位です。

let bitmap =
  [
    0; 0; 0; 0; 1; 0; 0; 0;
    0; 0; 0; 1; 1; 0; 0; 0;
    0; 0; 0; 0; 1; 0; 0; 0;
    0; 0; 0; 0; 1; 0; 0; 0;
    0; 0; 0; 0; 1; 0; 0; 0;
    0; 0; 0; 0; 1; 0; 0; 0;
    0; 0; 0; 0; 1; 0; 0; 0;
    0; 0; 0; 1; 1; 1; 0; 0;
  ] [@ocamlformat "disable"]
  |> List.map string_of_int |> String.concat ""

let commented_list =
  [
    0x00; (* 0x00 *)
    0x01; (* 0x01 *)
    0x02; (* 0x02 *)
    0x00; (* 0x00 *)
    0x01; (* 0x01 *)
    0x02; (* 0x02 *)
    0x00; (* 0x00 *)
    0x01; (* 0x01 *)
    0x02; (* 0x02 *)
    0x00; (* 0x00 *)
    0x01; (* 0x01 *)
    0x02; (* 0x02 *)
  ]
[@@ocamlformat "disable"]

注釈

  1. 正確には @ は “closest node” らしいです(参考)。