HelloHere is the latest OCaml Weekly News, for the week of March 26 to April
02, 2019.
Table of Contents ───────────────── Cstruct.4.0.0: sexplib goes optional New library - uritemplate 0.1.0 Check opam's health for the upcoming OCaml release (4.08) Turn echoing off on standard input to read e.g. passwords http2/af: An HTTP/2 implementation for OCaml Release of OCamlFormat 0.9 Other OCaml News Old CWN Cstruct.4.0.0: sexplib goes optional ════════════════════════════════════ Archive: <https://discuss.ocaml.org/t/cstruct-4-0-0-sexplib-goes-optional/3580/1> Anil Madhavapeddy announced ───────────────────────────A headsup about a forthcoming backwards incompatible change to the cstruct 4.0.0 release. We've been reducing the required dependencies of the core Mirage libraries to make the 'hello world' unikernels as small as possible. As part of that, cstruct (along with its good friends ipaddr and uri) have moved sexplib into a separate optional
module. From the changes file:• Sexplib is now an optional library for the base `Cstruct' module. A new `Cstruct_sexp' module has been introduced with the serialiser
functions, contained within the `cstruct-sexp' opam package. To convert old code, simply use `Cstruct_sexp.t' instead of`Cstruct.t' in a record type for which you are using `[@@deriving sexp]'. This is a type alias to `Cstruct.t' but also has the right sexp-conversion functions in scope. There is an example of this in
the `ppx_test/with-sexp' directory in the source repo. When you have converted and released your library, add an opamconstraint of `cstruct {>="4.0.0"}' to your own opam packages to
ensure that they pick up this version of the library. The opam repository PR with the full changeset is at : <https://github.com/ocaml/opam-repository/pull/13748> New library - uritemplate 0.1.0 ═══════════════════════════════ Archive: <https://discuss.ocaml.org/t/new-library-uritemplate-0-1-0/3588/1> Corin Chaplin announced ─────────────────────── I am happy to announce my first library published to opam:uritemplate! The library is a OCaml implementation of URI templates
([RFC6570]).Currently it only provides basic functionality but is compliant to
level 4 of the specification. I am looking at adding morefunctionality, such as a Template.t type, so templates can be parsed
and then templated multiple times. The repository is [here], the README and documentation is a bitlacking at the moment, but any feedback would be very much appreciated
:slight_smile: [RFC6570] <https://tools.ietf.org/html/rfc6570> [here] <https://github.com/CorinChappy/uritemplate-ocaml> Check opam's health for the upcoming OCaml release (4.08) ═════════════════════════════════════════════════════════ Archive: <https://discuss.ocaml.org/t/check-opams-health-for-the-upcoming-ocaml-release-4-08/3586/1> Kate announced ──────────────Like [last month], I'm here to announce new features and news from
[check.ocamllabs.io]. To recall, this website is an interface to find out which opampackages are broken with a given set of OCaml compilers. This month's features are especially useful to look for missing or broken packages
for the upcoming OCaml 4.08. What's new: • A new type of failures has appeared: internal failures (inwhite). Those were previously mistakenly categorized as a normal
build failure but are usually far from it. It includes: solverfailures, unavailable external dependencies, temporary misc server
failures, … • Not available packages are now not skipped but have now logs attached to them. It makes the total check run longer but isextremely useful to understand why does packages are not available
(e.g. which dependencies are blocking, …) Minor features: • I have adopted a new name for the underlying tool: [opam-health-check]• Under advice from @kkazuo, @grayswandyr and @Ronan in the previous post, I have adopted a new colour palette less ambiguous to both
colorblinds and non-colorblinds (at least I hope) • Slack integration (see more below) What's next: • Due to the ever growing number of opam packages and solvershenanigans, some solver failures can appear, especially on a server
with a lot of packages building in parallel. For nowopam-health-check uses the [SYMPHONY] solver instead of the builtin solver to mitigate that. However some failures still appear and I'm
looking to use a custom branch of opam that uses [Z3] instead.• I'm still meaning to add a revdeps counter soon as it is especially useful for new compiler releases (suggested by @bluddy a while ago,
see previous post)• Discuss and email integration, to send a message every time a run has finished (every 3-4 days). For now only Slack has just been
integrated.As OCaml 4.08 will be somewhat soon released, I'm inviting everyone (especially maintainers), with some spare time and will power, to have
a look at the main page with those filters: [Chase down non-available/broken opam packages for OCaml 4.08]For maintainers you can filter yourself and get only the packages you
are maintaining, using the form for this purpose. Happy hunt./Side note: for now the diff page is going to show garbage data due to
a server failure during the previous run/ [last month] <https://discuss.ocaml.org/t/check-ocamllabs-io-new-features-and-call-to-rename/3373> [check.ocamllabs.io] <http://check.ocamllabs.io>[opam-health-check] <https://github.com/kit-ty-kate/opam-health-check>
[SYMPHONY] <https://github.com/coin-or/SYMPHONY> [Z3] <https://github.com/Z3Prover/z3> [Chase down non-available/broken opam packages for OCaml 4.08] <http://check.ocamllabs.io/?comp=4.07.1&comp=4.08.0+beta2&available=4.07.1&available=4.08.0+beta2&show-diff-only=true> Turn echoing off on standard input to read e.g. passwords ═════════════════════════════════════════════════════════ Archive: <https://sympa.inria.fr/sympa/arc/caml-list/2019-03/msg00064.html> Helmut Brandl asked ───────────────────Is there a portable way in ocaml to turn echoing off on standard input from the terminal to read e.g. passwords? By portable I mean that it
works for Windows, Unix and Mac. Matthew Ryan replied ──────────────────── The usual way to do this (for any language) is using ANSI escapesequences. Code 8 sets the terminal to conceal characters and code 0
resets the attributes, making them visible again.For example, in a unix shell you can test this with echo and read:
echo -e '\x1b[8m'; read varname; echo -e '\x1b[0m' To do the same from OCaml, you can output "\x1b[8m", read thepassword, and then output "\x1b[0m" afterwards to switch printing back
on.I believe that this will work on Windows 10, but earlier versions may
not have the necessary ANSI support. Daniel Bünzli also replied ──────────────────────────Just for refence another way (that will in no way work on Windows) is to temporarily tweak the terminal attributes. The ocamlunix book shows
how to do this [here][1].In contrast to ANSI escapes which I believe is just a rendering trick that snippet will not allow to cut and paste the input password to recover it, whether that's a property you care about or not is up to
your use case. Best, Daniel [1]: <https://ocaml.github.io/ocamlunix/files.html#sec49> Chet Murthy said ──────────────── A little Googling turns up that the author of the Unix library(Xavier, IIRC) provided support for termios(3). So you can already do
what you want in Ocaml with no extra C ugly bits. Here's a little ocaml program to demonstrate, and after it, somestrace output showing the way it calls ioctl(2) to manipulate the line
discipline (relevant bits bolded in HTML format mail). ┌──── │ let main () = │ let open Unix in │ let tios = tcgetattr stdin in │ Printf.printf "c_echo: %b\n" tios.c_echo ; │ Printf.printf "c_echoe: %b\n" tios.c_echoe ; │ Printf.printf "c_echok: %b\n" tios.c_echok ; │ Printf.printf "c_echonl: %b\n" tios.c_echonl ; │ flush Pervasives.stdout ; │ tios.c_echo <- false ; │ tcsetattr stdin TCSANOW tios ; │ let tios = tcgetattr stdin in│ Printf.printf "AFTER c_echo: %b\nSleeping 10 sec ....\n" tios.c_echo ;
│ flush Pervasives.stdout ; │ Unix.sleep 10; │ tios.c_echo <- true ; │ tcsetattr stdin TCSANOW tios ; │ () │ ;; │ │ main() ;; └──── ┌──── │ $ strace -eioctl ./noecho │ ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0 │ c_echo: true │ c_echoe: true │ c_echok: true │ c_echonl: false │ ioctl(0, TCGETS, {B38400 opost isig icanon *echo* ...}) = 0 │ ioctl(0, TCGETS, {B38400 opost isig icanon *echo* ...}) = 0│ ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon *-echo *...})
│ = 0 │ ioctl(0, TCGETS, {B38400 opost isig icanon *-echo *...}) = 0 │ ioctl(0, TCGETS, {B38400 opost isig icanon *-echo* ...}) = 0 │ AFTER c_echo: false │ Sleeping 10 sec .... │ ioctl(0, TCGETS, {B38400 opost isig icanon *-echo* ...}) = 0 │ ioctl(0, TCGETS, {B38400 opost isig icanon *-echo* ...}) = 0│ ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon *echo* ...})
│ = 0 │ ioctl(0, TCGETS, {B38400 opost isig icanon *echo* ...}) = 0 │ +++ exited with 0 +++ └──── Jeremie Dimino also replied ───────────────────────────If you don't mind the extra dependency, there is a complete example in
the lambda-term library: <https://github.com/ocaml-community/lambda-term/blob/master/examples/read_password.ml>The main differences with the other solutions mentioned in this thread are that this version works on Windows, supports line edition and supports customisation such as displaying nothing or displaying stars.
http2/af: An HTTP/2 implementation for OCaml ════════════════════════════════════════════ Archive: <https://discuss.ocaml.org/t/ann-http2-af-an-http-2-implementation-for-ocaml/3578/1> Antonio Nuno Monteiro announced ───────────────────────────────I'm pleased to announce the product of a few months of work: an HTTP/2
implementation written entirely in OCaml: http2/af.http2/af is based on the concepts in [http/af], using Angstrom and Faraday for the parsing and serialization of the HTTP/2 framing layer,
respectively. It also preserves the same API as http/af wherever possible, for familiarity reasons. The notable exception is theaddition of a `Reqd.push' function that implements the HTTP/2 [server
push] functionality. http2/af currently provides a server implementation, as well asruntime implementations for Lwt (UNIX) and Mirage (which I implemented
at the last Mirage Hack Retreat in Marrakech).The repo for http2/af is [here]. The packages are not yet released to
OPAM, a task I'm planning to complete in the next few days.Happy to hear any feedback / answer questions here or in Github issues
(<https://github.com/anmonteiro/http2af/issues>). [http/af] <https://github.com/inhabitedtype/httpaf/>[server push] <https://httpwg.org/specs/rfc7540.html#PushResources>
[here] <https://github.com/anmonteiro/http2af> Antonio Nuno Monteiro later added ─────────────────────────────────There were some licensing issues in this work related to oversights and ignorance on my part. I’m copying a text from a Reddit post of
mine that tries to clarify the situation below.Thanks everyone who brought all the licensing issues to my attention.
To clarify: I never intended to “steal” any code, I.e. passing work as mine without proper attribution to the original authors. The truth is that, while I’ve been doing open source for a little while, this is the first time that I’ve done any derivative work, and not being a lawyer, I really had no idea what exactly I needed to do (my thought process being that if my code didn’t bear any resemblance at all to
the original code then I wouldn’t need to preserve the copyright headers). It has been brought to my attention that I was wrong and I have therefore rectified the situation. To clarify further what h2 is in comparison to http/af: h2 is animplementation of HTTP/2 (a totally different protocol) that tries to share the http/af types and API wherever possible. I understand now that this is derivative work because it shares the same underlying
architecture, but I didn’t know that coming into it at first.To all the affected parties: my apologies, I hope you can forgive me.
Release of OCamlFormat 0.9 ══════════════════════════ Archive: <https://discuss.ocaml.org/t/ann-release-of-ocamlformat-0-9/3589/1> Guillaume Petiot announced ────────────────────────── *Release of OCamlFormat 0.9*We are pleased to announce the release of OCamlFormat (available on opam). There have been numerous changes since the last release, so here is a comprehensive list of the new features and breaking changes
to help the transition from OCamlFormat 0.8. Dependencies ╌╌╌╌╌╌╌╌╌╌╌╌ OCamlFormat now requires: • ocaml >= 4.05 (up from 4.04.1) • dune >= 1.1.1 • octavius >= 1.2.0 • uutf OCamlFormat_Reason now requires: • ocaml >= 4.05 • dune >= 1.1.1 • ocaml-migrate-parsetree >= 1.0.10 (up from 1.0.6) • octavius >= 1.2.0 • uutf • reason >= 3.2.0 (up from 1.13.4) New preset profiles ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌The `ocamlformat' profile aims to take advantage of the strengths of a parsetree-based auto-formatter, and to limit the consequences of the weaknesses imposed by the current implementation. This is a style which optimizes for what the formatter can do best, rather than to
match the style of any existing code. General guidelines that have directed the design include:• Legibility, in the sense of making it as hard as possible for quick
visual parsing to give the wrong interpretation, is of highest priority;• Whenever possible the high-level structure of the code should be obvious by looking only at the left margin, in particular, it should not be necessary to visually jump from left to right hunting for
critical keywords, tokens, etc; • All else equal compact code is preferred as reading withoutscrolling is easier, so indentation or white space is avoided unless
it helps legibility;• Attention has been given to making some syntactic gotchas visually
obvious. `ocamlformat' is the new default profile.The `conventional' profile aims to be as familiar and "conventional"
appearing as the available options allow. The `default' profile is `ocamlformat' with `break-cases=fit'. `default' is deprecated and will be removed in version 0.10. OCamlFormat diff tool ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌`ocamlformat-diff' is a tool that uses OCamlFormat to apply the same formatting to compared OCaml files, so that the formatting differences between the two files are not displayed. Note that `ocamlformat-diff'
comes in a separate opam package and is not included in the `ocamlformat' package. The file comparison is then performed by any diff backend.The options' documentation is available through `ocamlformat-diff
--help'.The option `--diff' allows you to configure the diff command that is used to compare the formatted files. The default value is the vanilla `diff', but you can also use `patdiff' or any other similar comparison
tool.`ocamlformat-diff' can be integrated with `git diff', as explained in
the [online documentation]. [online documentation] <https://github.com/ocaml-ppx/ocamlformat/blob/master/tools/ocamlformat-diff/README.md> Formatting docstrings ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌Previously, the docstrings `(** This is a docstring *)' could only be formatted like regular comments, a new option `--parse-docstrings' has
been added so that docstrings can be nicely formatted. Here is a small example: ┌──── │ (** {1 Printers and escapes used by Cmdliner module} *) ││ val subst_vars : subst:(string -> string option) -> Buffer.t -> string -> string │ (** [subst b ~subst s], using [b], substitutes in [s] variables of the form │ "$(doc)" by their [subst] definition. This leaves escapes and markup
│ directives $(markup,...) intact. │ @raise Invalid_argument in case of illegal syntax. *) └────Note that this option is disabled by default and you have to set it
manually by adding `--parse-docstrings' to your command line or`parse-docstrings=true' to your `.ocamlformat' file. If you get the
following error message: Error: Formatting of (** … *) is unstable (e.g. parses as a list or not depending on the margin), please tighten up this comment in the source or disable the formatting using the option –no-parse-docstrings.It means the original docstring cannot be formatted (e.g. because it
does not comply with the odoc syntax) and you have to edit it or disable the formatting of docstrings.Of course if you think your docstring complies with the odoc syntax and there might be a bug in OCamlFormat, [feel free to file an issue
on github]. [feel free to file an issue on github] <https://github.com/ocaml-ppx/ocamlformat/issues> Print the configuration ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌The new `--print-config' flag prints the configuration determined by the environment variable, the configuration files, preset profiles and
command line. Attributes are not considered.It provides the full list of options with the values they are set to,
and the source of this value. For example `ocamlformat --print-config' prints: ┌──── │ profile=ocamlformat (file .ocamlformat:1) │ quiet=false (profile ocamlformat (file .ocamlformat:1)) │ max-iters=10 (profile ocamlformat (file .ocamlformat:1)) │ comment-check=true (profile ocamlformat (file .ocamlformat:1)) │ wrap-fun-args=true (profile ocamlformat (file .ocamlformat:1)) │ wrap-comments=true (file .ocamlformat:5) │ type-decl=compact (profile ocamlformat (file .ocamlformat:1))│ space-around-collection-expressions=false (profile ocamlformat (file .ocamlformat:1)) │ single-case=compact (profile ocamlformat (file .ocamlformat:1)) │ sequence-style=separator (profile ocamlformat (file .ocamlformat:1))
│ parse-docstrings=true (file .ocamlformat:4)│ parens-tuple-patterns=multi-line-only (profile ocamlformat (file .ocamlformat:1)) │ parens-tuple=always (profile ocamlformat (file .ocamlformat:1))
│ parens-ite=false (profile ocamlformat (file .ocamlformat:1))│ ocp-indent-compat=false (profile ocamlformat (file .ocamlformat:1)) │ module-item-spacing=sparse (profile ocamlformat (file .ocamlformat:1))
│ margin=77 (file .ocamlformat:3) │ let-open=preserve (profile ocamlformat (file .ocamlformat:1))│ let-binding-spacing=compact (profile ocamlformat (file .ocamlformat:1))
│ let-and=compact (profile ocamlformat (file .ocamlformat:1))│ leading-nested-match-parens=false (profile ocamlformat (file .ocamlformat:1)) │ infix-precedence=indent (profile ocamlformat (file .ocamlformat:1)) │ indicate-nested-or-patterns=space (profile ocamlformat (file .ocamlformat:1)) │ indicate-multiline-delimiters=true (profile ocamlformat (file .ocamlformat:1)) │ if-then-else=compact (profile ocamlformat (file .ocamlformat:1))
│ field-space=tight (profile ocamlformat (file .ocamlformat:1))│ extension-sugar=preserve (profile ocamlformat (file .ocamlformat:1)) │ escape-strings=preserve (profile ocamlformat (file .ocamlformat:1)) │ escape-chars=preserve (profile ocamlformat (file .ocamlformat:1)) │ doc-comments-tag-only=default (profile ocamlformat (file .ocamlformat:1)) │ doc-comments-padding=2 (profile ocamlformat (file .ocamlformat:1))
│ doc-comments=after (profile ocamlformat (file .ocamlformat:1)) │ disable=false (profile ocamlformat (file .ocamlformat:1)) │ cases-exp-indent=4 (profile ocamlformat (file .ocamlformat:1)) │ break-struct=force (profile ocamlformat (file .ocamlformat:1))│ break-string-literals=wrap (profile ocamlformat (file .ocamlformat:1)) │ break-sequences=false (profile ocamlformat (file .ocamlformat:1)) │ break-separators=before (profile ocamlformat (file .ocamlformat:1)) │ break-infix-before-func=true (profile ocamlformat (file .ocamlformat:1))
│ break-infix=wrap (profile ocamlformat (file .ocamlformat:1))│ break-fun-decl=wrap (profile ocamlformat (file .ocamlformat:1)) │ break-collection-expressions=fit-or-vertical (profile ocamlformat (file .ocamlformat:1))
│ break-cases=fit (file .ocamlformat:2) └────If many input files are specified, only print the configuration for
the first file. If no input file is specified, print theconfiguration for the root directory if specified, or for the current
working directory otherwise. Parentheses around if-then-else branches ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌A new option `parens-ite' has been added to decide whether to use parentheses around if-then-else branches that spread across multiple
lines. If this option is set, the following function: ┌──── │ let rec loop count a = │ if count >= self#len │ then a │ else │ let a' = f cur#get count a in │ cur#incr (); │ loop (count + 1) a' └──── will be formatted as: ┌──── │ let rec loop count a = │ if count >= self#len │ then a │ else ( │ let a' = f cur#get count a in │ cur#incr (); │ loop (count + 1) a' ) └──── Parentheses around tuple patterns ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ A new option `parens-tuple-patterns' has been added, that mimics`parens-tuple' but only applies to patterns, whereas `parens-tuples' only applies to expressions. `parens-tuple-patterns=multi-line-only' mode will try to skip parentheses for single-line tuple patterns, this is the default value. `parens-tuple-patterns=always' always uses
parentheses around tuples patterns. For example: ┌──── │ (* with parens-tuple-patterns=always *) │ let (a, b) = (1, 2) │ │ (* with parens-tuple-patterns=multi-line-only *) │ let a, b = (1, 2) └──── Single-case pattern-matching expressions ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌The new option `single-case' defines the style of pattern-matching expressions with only a single case. `single-case=compact' will try to format a single case on a single line, this is the default value. `single-case=sparse' will always break the line before a single case.
For example: ┌──── │ (* with single-case=compact *) │ try some_irrelevant_expression │ with Undefined_recursive_module _ -> true │ │ (* with single-case=sparse *) │ try some_irrelevant_expression │ with │ | Undefined_recursive_module _ -> true └──── Space around collection expressions ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌The new option `space-around-collection-expressions' decides whether to add a space inside the delimiters of collection expressions (lists,
arrays, records). For example: ┌──── │ (* by default *) │ type wkind = {f : 'a. 'a tag -> 'a kind} │ let l = ["Nil", TCnoarg Thd; "Cons", TCarg (Ttl Thd, tcons)] │ │ (* with space-around-collection-expressions *) │ type wkind = { f : 'a. 'a tag -> 'a kind } │ let l = [ "Nil", TCnoarg Thd; "Cons", TCarg (Ttl Thd, tcons) ] └──── Break separators ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌The new option `break-separators' decides whether to break before or after separators such as `;' in list or record expressions, `*' in tuples or `->' in arrow types. `break-separators=before' breaks the
expressions before the separator, this is the default value.`break-separators=after' breaks the expressions after the separator. `break-separators=after-and-docked' breaks the expressions after the
separator and docks the brackets for records. For example: ┌──── │ (* with break-separators=before *) │ type t =│ { foooooooooooooooooooooooo: foooooooooooooooooooooooooooooooooooooooo │ ; fooooooooooooooooooooooooooooo: fooooooooooooooooooooooooooo }
│ │ (* with break-separators=after *) │ type t =│ { foooooooooooooooooooooooo: foooooooooooooooooooooooooooooooooooooooo; │ fooooooooooooooooooooooooooooo: fooooooooooooooooooooooooooo }
│ │ (* with break-separators=after-and-docked *) │ type t = {│ foooooooooooooooooooooooo: foooooooooooooooooooooooooooooooooooooooo;
│ fooooooooooooooooooooooooooooo: fooooooooooooooooooooooooooo │ } └──── Not breaking before bind/map operators ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌The new option `break-infix-before-func' decides whether to break
infix operators whose right arguments are anonymous functionsspecially. This option is set by default, if you disable it with `--no-break-infix-before-func', it will not break before the operator so that the first line of the function appears docked at the end of
line after the operator. For example: ┌──── │ (* by default *) │ f x │ >>= fun y -> │ g y │ >>= fun () ->│ f x >>= fun y -> g y >>= fun () -> f x >>= fun y -> g y >>= fun () -> y ()
│ │ (* with break-infix-before-func = false *) │ f x >>= fun y -> │ g y >>= fun () ->│ f x >>= fun y -> g y >>= fun () -> f x >>= fun y -> g y >>= fun () -> y ()
└──── Break toplevel cases ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌There is a new value for the `break-cases' option: `toplevel', that forces top-level cases (i.e. not nested or-patterns) to break across
lines, otherwise breaks naturally at the margin. For example: ┌──── │ let f = │ let g = function │ | H when x y <> k -> 2 │ | T | P | U -> 3 │ in │ fun x g t h y u -> │ match x with │ | E -> 4 │ | Z | P | M -> ( │ match y with │ | O -> 5 │ | P when h x -> ( │ function │ | A -> 6 ) ) └──── Number of spaces before docstrings ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌The new option `doc-comments-padding' controls how many spaces are printed before doc comments in type declarations. The default value
is 2. For example: ┌──── │ (* with doc-comments-padding = 2 *) │ type t = {a: int (** a *); b: int (** b *)} │ │ (* with doc-comments-padding = 1 *) │ type t = {a: int (** a *); b: int (** b *)} └──── Ignore files ╌╌╌╌╌╌╌╌╌╌╌╌An `.ocamlformat-ignore' file specifies files that OCamlFormat should
ignore. Each line in an `.ocamlformat-ignore' file specifies a filename relative to the directory containing the`.ocamlformat-ignore' file. Lines starting with `#' are ignored and
can be used as comments. Here is an example of such `.ocamlformat-ignore' file: ┌──── │ #This is a comment │ dir2/ignore_1.ml └──── Tag-only docstrings ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌The new option `doc-comments-tag-only' controls the position of doc comments only containing tags. `doc-comments-tag-only=default' means
no special treatment is done, this is the default value.`doc-comments-tag-only=fit' puts doc comments on the same line if it
fits. For example: ┌──── │ (* with doc-comments-tag-only = default *) │ │ (** @deprecated *) │ open Module │ │ (* with doc-comments-tag-only = fit *) │ │ open Module (** @deprecated *) └──── Fit or vertical mode for if-then-else ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌There is a new value for the option `if-then-else': `fit-or-vertical'. `fit-or-vertical' vertically breaks all branches if they do not fit on a single line. Compared to the `compact' (default) value, it breaks all branches if at least one of them does not fit on a single line.
For example: ┌──── │ (* with if-then-else = compact *) │ let _ = │ if foo then │ let a = 1 in │ let b = 2 in │ a + b │ else if foo then 12 │ else 0 │ │ (* with if-then-else = fit-or-vertical *) │ let _ = │ if foo then │ let a = 1 in │ let b = 2 in │ a + b │ else if foo then │ 12 │ else │ 0 └──── Check mode ╌╌╌╌╌╌╌╌╌╌A new `--check' flag has been added. It checks whether the input files already are formatted. This flag is mutually exclusive with `--inplace' and `--output'. It returns `0' if the input files are
indeed already formatted, or `1' otherwise. Break function declarations ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ The new option `break-fun-decl' controls the style for function declarations and types. `break-fun-decl=wrap' breaks only if necessary, this is the default value.`break-fun-decl=fit-or-vertical' vertically breaks arguments if they
do not fit on a single line. `break-fun-decl=smart' is like`fit-or-vertical' but try to fit arguments on their line if they fit. The `wrap-fun-args' option now only controls the style for function
calls, and no more for function declarations. For example: ┌──── │ (* with break-fun-decl = wrap *)│ let ffffffffffffffffffff aaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbb
│ cccccccccccccccccccccc = │ g │ │ (* with break-fun-decl = fit-or-vertical *) │ let ffffffffffffffffffff │ aaaaaaaaaaaaaaaaaaaaaa │ bbbbbbbbbbbbbbbbbbbbbb │ cccccccccccccccccccccc = │ g │ │ (* with break-fun-decl = smart *) │ let ffffffffffffffffffff│ aaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccc =
│ g └──── Disable configuration in files and attributes ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌Two new options have been added so that `.ocamlformat' configuration files and attributes in OCaml files do not change the configuration. These options can be useful if you use some preset profile and you do not want attributes and `.ocamlformat' files to interfere with your
preset configuration. `--disable-conf-attrs' disables the configuration in attributes, and `--disable-conf-files' disables `.ocamlformat' configuration files. Preserve module items spacing ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌There is a new value for the option `module-item-spacing': `preserve', that will not leave open lines between one-liners of similar sorts
unless there is an open line in the input. For example the line breaks are preserved in the following code: ┌──── │ let cmos_rtc_seconds = 0x00 │ let cmos_rtc_seconds_alarm = 0x01 │ let cmos_rtc_minutes = 0x02 │ │ let x = o │ │ let log_other = 0x000001 │ let log_cpu = 0x000002 │ let log_fpu = 0x000004 └──── Breaking changes ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ • When `--disable-outside-detected-project' is set, disable ocamlformat when no `.ocamlformat' file is found. • Files are not parsed when ocamlformat is disabled. • Disallow `-' with other input files.• The `wrap-fun-args' option now only controls the style for function
calls, and no more for function declarations. • The default profile is now named `ocamlformat'.• The deprecated syntax for `.ocamlformat' files: `option value' is no
more supported anymore and you should use the `option = value' syntax instead. Miscellaneous bugfixes ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌• Preserve shebang (e.g. `#!/usr/bin/env ocaml') at the beginning of a
file. • Improve the formatting when `ocp-indent-compat' is set. • UTF8 characters are now correctly printed in comments.• Add parentheses around a constrained any-pattern (e.g. `let (_ :
int) = x1'). • Emacs: the temporary buffer is now killed. • Emacs: add the keybinding in tuareg's map instead of merlin's. • Lots of improvements on the comments, docstrings, attributes formatting. • Lots of improvements on the formatting of modules. • Lots of improvements in the Reason support. • Do not rely on the file-system to format sources. • The `--debug' mode is more user-friendly. Credits ╌╌╌╌╌╌╌This release also contains many other changes and bug fixes that we
cannot detail here.Special thanks to our maintainers and contributors for this release: Jules Aguillon, Mathieu Barbin, Josh Berdine, Jérémie Dimino, Hugo Heuzard, Ludwig Pacifici, Guillaume Petiot, Nathan Rebours and Louis
Roché.If you wish to get involved with OCamlFormat development or file an
issue, please read the [contributing guide], any contribution is welcomed. [contributing guide] <https://github.com/ocaml-ppx/ocamlformat/blob/master/CONTRIBUTING.md> Other OCaml News ════════════════ From the ocamlcore planet blog ──────────────────────────────Here are links from many OCaml blogs aggregated at [OCaml Planet].
• [OCaml on Baremetal Shakti RISC-V processor] • [Release of OCamlFormat 0.9] [OCaml Planet] <http://ocaml.org/community/planet/> [OCaml on Baremetal Shakti RISC-V processor] <http://kcsrk.info/ocaml/riscv/shakti/2019/03/29/1400-ocaml-baremetal-shakti/> [Release of OCamlFormat 0.9] <https://tarides.com/blog/2019-03-29-release-of-ocamlformat-0-9.html> Old CWN ═══════If you happen to miss a CWN, you can [send me a message] and I'll mail it to you, or go take a look at [the archive] or the [RSS feed of the
archives].If you also wish to receive it every week by mail, you may subscribe
[online]. [Alan Schmitt] [send me a message] <mailto:alan.schm...@polytechnique.org> [the archive] <http://alan.petitepomme.net/cwn/>[RSS feed of the archives] <http://alan.petitepomme.net/cwn/cwn.rss>
[online] <http://lists.idyll.org/listinfo/caml-news-weekly/> [Alan Schmitt] <http://alan.petitepomme.net/>
signature.asc
Description: PGP signature
_______________________________________________ caml-news-weekly mailing list caml-news-weekly@lists.idyll.org http://lists.idyll.org/listinfo/caml-news-weekly