The logic to create utop from utop-full is as follows:
- use ocamlobjinfo on utop-full to determine which modules are used
- use ocamlobjinfo on ocamlcommon, ocamlbytecomp, and ocamltoplevel to
determine which modules to exclude (a priori)
- compute the set used - (exclude - {Topmain,Toploop,Topdirs})
- call expunge with this set of modules
Previously, this was all done in expunge/expunge.ml, meaning core logic
+ process handling.
What this PR does is offload the process handling to dune: calling
ocamlobjinfo and expunge is done instead in dune rules, and
expunge/modules.ml is just about reading sets of module names and
outputing the result.
Besides simplicity and portability, the other advantage is that the
intermediate modules.txt can be inspected directly.
Fixes#428
The change in #418 introduced a regression if a `Unit` module in scope
does not have a `()` constructor in it.
This switches to the more explicit `Stdlib.Unit.()` path.
We are building a hidden expression that contains "()" but it is not
qualified. So it will pick the constructor in scope. This can cause
problems if `()` has been redefined. The correct fix is to qualify it as
part of the `Unit` module.
(additionally, this removes an unused ident)
Fixes#417
The utop code base is full of #if OCAML_VERSION to adapt to the changes
in compiler-libs. This has some issues - for example the corresponding
logic is harder to recognize, and some logic is duplicated in several
places. Also, this prevents using a formatter.
One medium-term goal is to move most of the compat functions to a new
Utop_compat module which would be the only place we use cppo.
This contains the "easy" cases - moving existing functions, etc. It is a
bit more difficult (and controversial) to convert pattern matching to
this pattern so it'll be done separately.
Exiting normally here refers to the `Exit_with_status` exception.
It is in particular triggered by `#quit;;` so we want to exit quietly
in that case.
Closes#398
* utop.el: always insert phrase terminator at the end-ish of input
When point is at the letter "n" in
utop[1]> let thi[n]g = 42
or in
utop[2]> let thi[n]g = 8734;
and the user presses C-j, it is always because they want to terminate
the expression at the end-ish of the input.
The unpatched behavior did not move point, and inserted two semicolons
in the middle of the expression.
Seems 9 years ago someone tried to extract types from the evaluation
results but never got this working. I think it's time for this code to
go away, given that we have much better options today (e.g. Merlin).
Utop supports a wide range of OCaml versions, but this is getting more
difficult to support. In addition, some of the dependencies we use do
not support 4.03-4.07, so utop can not be built on these versions.
Those are extremely common in Emacs modes and allow people to
quickly jump to a REPL and back to the last source buffer they
were editing, while using the same keybinding.
I've modeled the implementation here after that of inf-clojure (a similar
mode written by me). I've also implemented a mode menu for
utop-minor-mode, so it's easier for the users to discover its
functionality.
Without those changes you won't get any completion for things like
"List.m". I'm not very familiar with the code, but it seems that the
backend returns the completion candidates without the module prefix
which caused the problem.
I've opted to fix this by handling prefixes with a "." in them specially
and this works fine in the limited testing I conducted locally.