2

When displaying long lists and other large values, utop wraps them at about 80 columns, even when my terminal window is wider. How can I change the output width?

The only thing that I have found that might have provided the solution is UTop.size, which has type LTerm_geom.size React.signal, and seems to correctly record the size of my terminal window. In this example my terminal window had dimensions 164x37:

# #require "react";;
# #require "lambda-term";;
# React.S.value UTop.size;;
- : LTerm_geom.size = {LTerm_geom.rows = 37; cols = 164}

However, the value of cols doesn't seem to affect how values are displayed. For example, this is copied from the same session (with line breaks as they were displayed):

# List.hd algs;;
- : (int list * float) list =
[([2; 1; 0], 1.); ([2; 1], 0.54148398267); ([2; 0], 0.677137905076);
 ([2], 0.218621887745); ([1; 0], 0.781378112255); ([1], 0.322862094924);
 ([0], 0.45851601733); ([], 0.)]
Mars
  • 8,689
  • 2
  • 42
  • 70

1 Answers1

2

There is a function called UTop.set_margin_function:

μ> #typeof "UTop.set_margin_function";;
val UTop.set_margin_function : (LTerm_geom.size -> int option) -> unit

Here is a simplistic example usage:

μ> UTop.set_margin_function (fun _ -> Some 150);;

After this point utop will use about 150 columns for printing out the results.

Here is an example session (shell + utop):

> utop -version
The universal toplevel for OCaml, version 1.19.3, compiled for OCaml version 4.04.1

> cat ~/.ocamlinit
(* Added by OPAM. *)
let () =
  try Topdirs.dir_directory (Sys.getenv "OCAML_TOPLEVEL_PATH")
  with Not_found -> ()
;;

> cat ~/.utoprc
cat: .utoprc: No such file or directory

> utop

utop # gen_nat_list 1 50;;   (* gen_nat_list is some test function *)
- : int list =
[1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20; 21; 22;
23; 24; 25; 26; 27; 28; 29; 30; 31; 32; 33; 34; 35; 36; 37; 38; 39; 40; 41;
42; 43; 44; 45; 46; 47; 48; 49; 50]

utop # UTop.set_margin_function (fun _ -> Some 150);;

utop # gen_nat_ist 1 50;;
- : int list =
[1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20; 21; 22; 23; 24; 25; 26; 27; 28; 29; 30; 31; 32; 33; 34; 35; 36; 37; 38; 39;
 40; 41; 42; 43; 44; 45; 46; 47; 48; 49; 50]
Anton Trunov
  • 15,074
  • 2
  • 23
  • 43
  • Thanks Anton. I saw that function at one point, but I couldn't make any sense of it. Thanks for explaining how to use it. However, I just tried your suggestion, and it seems to have no effect. I thought that maybe I needed to run as utop is starting up, so I put it in .ocamlinit, but that doesn't do anything either. – Mars May 02 '17 at 16:38
  • I think that the original definition of `set_margin_function` is in uTop_private.ml: `let margin_function, set_margin_function = S.create ~eq:( == ) (fun (size : LTerm_geom.size) -> Some (min 80 size.cols))`. I don't fully understand the definition, but maybe `min 80 size.cols` is the problem? I wonder if that was supposed to be `max`. There is also a function `set_margin` defined there that I don't understand and can't figure out how to access. – Mars May 02 '17 at 16:59
  • 1
    Perhaps my next step should be to add an issue in github. There ought to be a way to set the output width, or for utop to automatically sense the terminal size, which seems to be what it's intended to do. – Mars May 02 '17 at 17:14
  • @Mars I updated my answer with an example shell + utop session. `UTop.set_margin_function` works for me. The session was on macOS, and I also tried it on my Ubuntu box, which gave the same result (with utop 1.19.2 using OCaml 4.03.0). In both cases utop was installed via opam. – Anton Trunov May 02 '17 at 20:35
  • Well that's weird. Works for me now, too. Are you sure you didn't sneak onto my machine and change something in my configuration? :-) Thanks. This makes utop more convenient for exploration. – Mars May 02 '17 at 21:54
  • 1
    In case anyone's interested, the problem I experienced using `set_margin_function` has something to do with changing the font size in the terminal. After I change the font size (using Apple+ or Apple- ), `set_margin_function` has no effect. This applies both to the terminal app that comes with El Capitan, and iTerm2, which is what I usually use. – Mars May 03 '17 at 05:31
  • I don't think my previous comment is correct. Still investigating. – Mars May 04 '17 at 02:40
  • 2
    It appears that lists whose elements are tuples or lists always wrap at 80 columns or less, even when `set_margin_function` causes lists with simple elements wrap at a margin > 80. I submitted an issue on github. – Mars May 04 '17 at 04:08