Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/manasjayanth/esy-mode
Emacs minor-mode for esy
https://github.com/manasjayanth/esy-mode
bucklescript esy ocaml reason reasonml
Last synced: 2 months ago
JSON representation
Emacs minor-mode for esy
- Host: GitHub
- URL: https://github.com/manasjayanth/esy-mode
- Owner: ManasJayanth
- License: mit
- Created: 2019-12-31T18:51:52.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2024-09-27T06:24:39.000Z (3 months ago)
- Last Synced: 2024-10-13T11:13:50.180Z (3 months ago)
- Topics: bucklescript, esy, ocaml, reason, reasonml
- Language: Emacs Lisp
- Homepage:
- Size: 109 KB
- Stars: 9
- Watchers: 1
- Forks: 2
- Open Issues: 8
-
Metadata Files:
- Readme: README.org
- Funding: .github/FUNDING.yml
- License: License
Awesome Lists containing this project
README
* esy-mode
=esy-mode= is a minor mode written for [[http://esy.sh][esy]] - the package manager for
Reason/OCaml development. It is meant to serve as a auxiliary plugin
that helps other plugins to find the correct path to the tools.For instance, it can help lsp-mode get the right path to ocaml
language server. It, however, doesn't ship the tools
themselves. =esy-mode= simply creates a buffer local environment for
the tools - which enables it to efficiently inform the user of
available/missing tools.If you are looking for a tool to have a great first working state,
checkout [[https://github.com/esy/pesy][pesy]]. Or simply clone the [[https://github.com/esy-ocaml/hello-reason][hello-reason]] repo.** Pre-requisites
This minor mode is meant to work with =esy= which is not shipped
here. Quickest way to get =esy= installed on your machine is to
install it globally using a nodejs package manager
#+BEGIN_SRC shell
npm i -g esy
# or
yarn global add esy
#+END_SRCNo, =esy= is not written in JS, but a prebuilt binary and is
currently only containing ones that work on 64 bit Windows, Linux
and MacOS. More details on the [[http://esy.sh][website]]You'll need to tweak =reason-mode= a bit so that the project setup is completely
=esy-mode's= hands.Example: [[https://github.com/prometheansacrifice/reason-mode/commit/e98f88a24491578461be85b2adf0dc5e354937cb][e98f88a244]]
TODO: make the tweaks less intrusive. Ping me on Discord if you need help with it.
** Installation
At the moment the package hasn't been published anywhere. Quickest
way to get started is to clone the repo and load it#+BEGIN_SRC shell
git clone https://github.com/prometheansacrifice/esy-mode
#+END_SRC#+BEGIN_SRC emacs-lisp
(load-file "/path/to/esy-mode/esy-mode.el")
#+END_SRCIf you use quelpa and use package, you can use the following
#+BEGIN_SRC emacs-lisp
(use-package
esy-mode
:quelpa (esy-mode :path "/path/to/esy-mode.el" :fetcher file)
:hook reason-mode
:config (progn
(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection '("ocamllsp"))
:major-modes '(reason-mode tuareg-mode)
:server-id 'esy-ocamlmerlin-lsp))))
#+END_SRC** Configuration
1. =esy-command= to specify full path to esy command if necessary. (Falls back to a just "esy')
2. =esy-mode-callback= to specify a callback that could run one all buffer local variables are initialised. For
more info on the buffer local variables, checkout the next section =How it works=.** How it works
All =npm= and =opam= managed Reason/OCaml projects are valid esy projects too.
This means, the minor mode must correctly distinguish them from actual =esy= projects
(which are basically Reason/OCaml source with build config files
shipped with an =esy.json= or a =package.json=).=esy= provides a =status= sub-command. Which can return an output
like this in the case of an esy project#+BEGIN_SRC js
{
"isProject": true,
"isProjectSolved": true,
"isProjectFetched": true,
"isProjectReadyForDev": true,
"rootBuildPath": "/path/to/g/foo/_esy/default/store/b/foo-03e8a06e",
"rootInstallPath": "/path/to/g/foo/_esy/default/store/i/foo-03e8a06e",
"rootPackageConfigPath": "/path/to/g/foo/esy.json"
}
#+END_SRCFor an opam project, it could look like
#+BEGIN_SRC js
{
"isProject": true,
"isProjectSolved": true,
"isProjectFetched": true,
"isProjectReadyForDev": true,
"rootBuildPath": "/path/to/ocaml/ocaml-lsp/_esy/default/store/b/ocaml_lsp-38a74123",
"rootInstallPath": "/path/to/ocaml/ocaml-lsp/_esy/default/store/i/ocaml_lsp-38a74123",
"rootPackageConfigPath": null
}
#+END_SRCSo,
1. All non-json manifest file driven projects, by looking up
=rootPackageConfigPath= property, are opam projects
2. Among json file driven projects,
1. Those with that are not package.json are esy projects
2. =package.json= with =esy= property are =esy= projects -
others were being managed by npm
Valid =esy= projects are straight forward to handle - the minor mode
checks if the project is in buildable state and prompts if it
isn't.=esy= provides the [[https://esy.sh/docs/en/environment.html][command environment]] (the environment where tools
like editors are supposed to run) as a json output. =esy-mode= loads
all complete environment in a buffer local
=process-environment=, giving each project workspace an identical
development environment. Here on, running =(executable-find ...)=
returns the dev tools from the =esy= sandbox, ensuring you and your
co-worker always have the same exact version of tools while
developing.
**** Why load the environment when one can simply `esy exec-command`?=esy exec-command = is a great approach. For good
editor experience, one might have to resort to =esy exec-command
command -v = repeatedly to check if the tool
exists and inform the user. =(executable-find ...)= is better
approach IMO. This is subject to how Emacs handles buffer local
process environments of course.
*** NPM and Bucklescript build system managed projects=npm= unfortunately doesn't provide prebuilts with reproducibility
guarantees, nor does it sandbox tools that need each other on the
path to work together. Mismatching compiler and [[https://github.com/ocaml/merlin][merlin]] prebuilts
cause a lot of confusion - using npm to install these tools
globally is not an easy experience for newcomers.Similarly, inter-tool interaction is not reliable in
global environments. For instance, =ocamlmerlin= expects
=ocamlmerlin-reason= binary to be available in it's path - and
both of these must be built with the *same* version of the
compiler. In the global environment, it was incredibly hard to get
them to work - user's system wide configuration is a complete
blackbox. The only reliable way to ensure interacting tools work
together is to run them in sandboxed environments - and =esy=
provides just that!This is why we recommend bucklescript users to allow editor
plugins to drop an =esy.json= - plugins look into the compiler
version and create this file themselves.*** Opam managed projects
This is a work in progress - =esy= provides sandboxed environments
for opam projects too (without creating any =esy.json=). But opam
users dont ship development time dependencies in their package
manifests. For now, the plugin stays inactive. Ideas are welcome.** Contributing guidelines
Currently beta quality. Looking forward to ideas and feedback. If
you're raising a PR, please add a test. Not having types to catch
your errors are hard - even if lisp somehow makes it bearable,
let's ensure we still try to catch errors early!
** LicenseMIT licensed. Please see LICENSE for more details