What are your major pains with the editor tooling? Round 2

Hey everyone!

We did a thread a good while back where we asked what your major pains using the VSCode tooling was: What are your major pains with the VSCode extension?. Since then we’ve worked on most of the things listed in that thread.

As we’ve almost released v11, I think it’s time for a new, updated edition of that thread. But first, I’d like to set the stage a little:

In order for us to be able to create really good and stable editor tooling, we’re all going to need to help out and go the extra mile to create reproductions, thorough bug reports and so on. So, please help us out with that! If you wonder how to “properly” report things, just ask and I’m happy to tell.

So, what are your major pains using the ReScript editor tooling as of today?

5 Likes

Losing correct hover info when there are unsaved lines above the hovered element, even if those lines parse perfectly. Would be cool if we could somehow track the offset and still display the correct info.

3 Likes

Hello :wave:

Thank you for the excellent work done on ReScript, it’s a pleasure to use this language every day. :clap:
I’ve identified some pains with the editor tooling. Here is a first selection

(the example repo: GitHub - LeoLeBras/rescript-major-pains-with-editor-tooling)

(1)

I have a WebAPI bindings file in my production project based on Rescript official Dom types.
But autocomplete doesn’t work well with my sub-module WebAPI.DomElement
webapi-issues

By writing myDomElement (of type Dom.element) , I’d like the extension to autocomplete the rest using my WebAPI module.

also note that auto-completion doesn’t work well within Option.map(…).


(2)

create-interface-with-externals

When generating an interface file for some bindings, the output file should be clean. This is not the case, so I have to delete the @x external annotation manually.


(3)

Here I’m writing a unit test. So I have bindings around expect test function.

test-real-world-example

Basically, the plugin doesn’t handle good DX for parameter types t<'a>. Some improvements :

  • The plugin should sort the results according to whether Expect.t<'a> is of type t<string> or t<array<'item>>.
  • If I write toHaveL, it should also provide me Expect.Array.toHaveLength autocompletion.

(4)

variant-poly-issue-2

Auto-completion on polymorphic variants on a React component doesn’t work.


(5)

issue-variant-poly-2

In the example, rather than writing #ban, I want to write ban directly …and auto-completion no longer works. If I delete my text, auto-completion doesn’t work either.
I have to delete the parenthesis to “fix” autocompletion.

(6)

record-autocomplete-2

There is no auto-completion if one of the function’s expected arguments is a record. When I write {}, it should suggest the record fields to fill in.


(7)

sorting-autocomplete-2

Suggestions are sorted alphabetically, but this doesn’t always make sense. (nitpick)
Here, my debugX functions are suggested first, but rarely used. They are defined at the end of my bindings file.


Typescript is known for its superb editor tooling.
But ReScript can compete with it if these improvements are made :pray:

3 Likes

This is great stuff! Could you please set up a repo where all of this can be reproduced easily?

The link is in my previous message
Here it is: GitHub - LeoLeBras/rescript-major-pains-with-editor-tooling

2 Likes

Type checking without saving the file.

Just a note on @LeoLeBras’s #2. I also wanted this functionality until I realized that cleaning up the interface file will actually change the compiler output. Take the example file SomeBinding.res:

type t = int

let make = () => 1

@send
external testMethod1: (t, int) => int = "testMethod"

@send
external testMethod2: (t, int) => int = "testMethod"

and interface SomeBinding.resi:

type t

let make: unit => t

let testMethod1: (t, int) => int

@send
external testMethod2: (t, int) => int = "testMethod"

Here’s example compiler output of the two methods in use:



import * as SomeBinding from "./SomeBinding.mjs";

var test1 = SomeBinding.testMethod1(SomeBinding.make(undefined), 1);

var test2 = SomeBinding.make(undefined).testMethod(1);

export {
  test1 ,
  test2 ,
}
/* test1 Not a pure module */

Since the compiler no longer has knowledge of the external from the outside, it has to introduce an extra function call. Not a big deal, but something to be aware of.

3 Likes

Okay, that makes sense :slight_smile:

1 Like

Rescript LSP has to be constantly restarted. It occasionally does down whenever there are errors in the code.

two things drive me nuts but they are kinda dumb but I think I’ve only experienced them with rescript

  1. I think completions should be case insensitive. If I’m lazy enough to want a completion, I’m also too lazy to remember if its capitalized or not.

  2. Doesn’t complete when you are “inserting”, or at least only some of the time, havent figure out exactly when

for example:

if you type

let x = doStuff()

and then realize you wanted

let x = doStuffWithOptions(opts)

if you have to erase the () to get the completion to kick in. Maybe this is an optimization to only do completions when there is whitespace after your cursor, so it isn’t constantly checking for completions while you type, but I think that might be an over optimization.

4 Likes

Have another one.

editor.action.rename.

Renaming a labeled argument doesn’t keep the ~

Would also be nice if it worked for modules (including changing the file name)

I’ve also seen it do weird things, but I don’t have an example handy right now, but I’m sure there’s a bug in there. When it happens again I’ll create a ticket.

1 Like

Thank you for the reports, great stuff! Keep them coming and I’ll try and spend some time time on fixing these things when I can.

I can’t really reproduce #2, could you expand on what you mean?

I’m having trouble reproducing this myself now. Maybe its a bugfoot.

Maybe I’m just getting the case wrong and its not completing. I’m going to keep an eye out for a reproducible example.