Code Monkey home page Code Monkey logo

company-mlton's Introduction

company-mlton

company-mlton is a company-mode completion back-end for MLton/Standard ML. It provides completion for Standard ML keywords and for Standard ML (long) identifiers. Candidate completion identifiers for the latter are loaded from a basis file created by mlton using -show-basis file or (*#showBasis "file"*).

Screenshot

`company-mlton` screenshot

Dependencies

Install Package via Git

Clone repository:

cd ~/.emacs.d
git clone https://github.com/MatthewFluet/company-mlton

Add to .emacs or init.el:

(add-to-list 'load-path "~/.emacs.d/company-mlton")
(require 'company-mlton)
(add-hook 'sml-mode-hook #'company-mlton-init)

Usage

Completion candidates for Standard ML (long) identifiers are loaded from a basis file created by mlton using -show-basis file or (*#showBasis "file"*).

Default Basis

company-mlton ships with a default basis file that corresponds to MLton’s default environment (implicitly used by mlton when compiling a .sml file). It includes the Standard ML Basis Library, structure Unsafe: UNSAFE, structure SMLofNJ: SML_OF_NJ, and structure MLton: MLTON (plus supporting signatures). This default basis is automatically used for sml-mode buffers that do not set the buffer-local variable company-mlton-basis-file. Thus, it provides useful completion for single-file .sml programs.

Custom Basis Workflows

For larger Standard ML programs, it can be more useful to load a custom basis file created by mlton using -show-basis file or (*#showBasis "file"*).

Using -show-basis file

In some projects, a common set of utility libraries are used by many source .sml files. For example, consider a project described as follows:

  • project.mlb:

    $(SML_LIB)/basis/basis.mlb
    $(SML_LIB)/smlnj-lib/Util/smlnj-lib.mlb
    $(SML_LIB)/smlnj-lib/Controls/controls-lib.mlb
    ../lib/PrettyPrint/PrettyPrint.mlb
    ../lib/ParserCombinators/ParserCombinators.mlb
    
    src1.sml
    src2.sml
    main.sml

Within src1.sml, src2.sml, and main.sml, it would be useful to complete with the common set of libraries. To do so, extract the "imports" of project.mlb to project-imports.mlb:

  • project-imports.mlb:

    $(SML_LIB)/basis/basis.mlb
    $(SML_LIB)/smlnj-lib/Util/smlnj-lib.mlb
    $(SML_LIB)/smlnj-lib/Controls/controls-lib.mlb
    ../lib/PrettyPrint/PrettyPrint.mlb
    ../lib/ParserCombinators/ParserCombinators.mlb
  • project.mlb:

    project-imports.mlb
    main.sml

Now, save the environment described by project-imports.mlb:

mlton -show-basis project-imports.basis -stop tc project-imports.mlb

Finally, arrange for the buffer-local variable company-mlton-basis-file to be set to project-imports.basis for each source .sml file. This can be accomplished by any of the following:

  • Execute M-x company-mlton-basis-load after loading a source .sml file and choose project-imports.basis at the prompt.

  • Add a file-local variables -*- line to each of the source .sml files:

    (* -*- company-mlton-basis-file: "project-imports.basis"; -*- *)

    A file-local variables -*- line must be the first line of the file.

  • Add a file-local variables Local Variables: block to each of the source .sml files:

    (* Local Variables: *)
    (* company-mlton-basis-file: "project-imports.basis" *)
    (* End: *)

    A file-local variables Local Variables: block is typically placed at the end of the file.

  • Add a .dir-locals.el file to the directory:

    ((sml-mode . ((company-mlton-basis-file . "project-imports.basis"))))

The advantage of the -show-basis file workflow is that the custom basis file need only be created once (or whenever the common set of libraries changes) and can be shared among many source .sml files. The disadvantage of the -show-basis file workflow is that the environment used for completion is not specialized to each source .sml file.

Using (*#showBasis "file"*)

More specialized completions for a particular source .sml file can be provided by using (*#showBasis "file"*) directives.

A comment of the form (*#showBasis "file"*) in a source .sml file is recognized by mlton as a directive to save the environment at that point to file. The file is interpreted relative to the source .sml file in which it appears. The comment is lexed as a distinct token and is parsed as a structure-level declaration.

Via company-mlton-init added to sml-mode-hook, comments of the form (*#showBasis "file"*) are recognized when a source .sml file is loaded and the buffer-local variable company-mlton-basis-file is set to file. Similarly, executing M-x company-mlton-basis-autodetect (or M-x company-mlton-init) will scan the current buffer for comments of the form (*#showBasis "file"*) and set the buffer-local variable company-mlton-basis-file accordingly; this can be used if the (*#showBasis "file"*) comment is added after the source .sml file is loaded.

A (*#showBasis "file"*) directive can be used to capture an environment that includes functor arguments, local structure aliases, and local structure declarations. For example, consider writing a type-checker module as a functor, parameterized by an abstract-syntax-tree represenation and a core representation and defining an environment module by applying a functor:

functor TypeCheck
   (S: sig
          structure Ast: AST_IR
          structure Core: CORE_IR
       end):
   sig
      val typeCheck: Ast.Prog.t -> Core.Prog.t option
   end =
struct
   open S

   structure A = Ast
   structure C = Core
   structure E =
      MkEnv (structure Dom = A.Var
             structure Rng =
                struct
                   type t = C.Var.t * C.Type.t
                end)

   (*#showBasis "type-check.basis"*)

   fun typeCheck p = raise Fail "typeCheck"

end

Compile (or at least type check) the whole project (or at least the portion of the project that includes type-check.fun) as usual. The environment saved to type-check.basis will include structure A, structure C, and structure E, in addition to all identifiers in scope at the start of the functor declaration.

The advantage of the (*#showBasis "file"*) workflow is that the custom basis file can be specialized to each source .sml file. It should also fit naturally into a workflow that frequently compiles the current work-in-progress source .sml file to check for type errors.

company-mlton's People

Contributors

matthewfluet avatar syohex avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.