Reputation: 937
Monaco Editor is very cool, but I've been beating my head against it for awhile, and the sparse documentation and uncommented examples they provide have not helped.
Here's my situation. Like so many other people, I am trying to get Monaco Editor to work with some custom classes of mine and make it easy for my user to easily see their methods and properties, both as suggestions and hovers. I am doing this in Javascript but I don't think the language matters all that much.
As an example, here is the kind of thing my user's code, typed into the Monaco Editor, might have in it:
var c = new MyClass(5);
c.myMethod("Hello there!");
So the above might correspond to a very simple class definition in my codebase (invisible to my user), like so:
/**
* MyClass
*
* This is my custom class.
*/
class MyClass {
constructor(initialValue) {
this.myProperty = initialValue;
}
/**
* myMethod
*
* This is a sample method.
*
* @args {string} val The value to store.
*
*/
myMethod(val) {
this.value = val;
}
}
Nothing too mysterious or exciting there. What I want in my Monaco Editor instance is that when someone starts to type c.
, they get an autosuggest list that includes myMethod
, and that contains a description. I also want so that if the user does have c.myMethod(blah)
and they hover over c
they get the class description, and if they hover over myMethod
they get the method description.
In an ideal world, I'd also have a way to insert a default value if they want to, but I'm not holding my breath on that one.
I'd also love it if when they typed c.
, they got an autosuggest for the properties of myProperty
and value
.
The three ways to do this in Monaco Editor that I have seen are:
Completion provider: Requires me to set up a bunch of separate data for each class/method/property, but executes the completion/suggestion part well, and allows me to insert default data if desired. Does NOT do hovers. Does NOT actually understand the code, is just looking for specific key triggers. So if I did var mc = new MyClass();
it would not know to trigger the autosuggest for mc.
unless I specifically told it that this particular string was a possible trigger. This is not necessarily a deal-breaker, since in my particular case it will always be the same variable name for the class, but it hints as the inflexibility of such an approach. Even then, I have had a hard time getting an example working that would trigger on something like c.
and not c.m
or some other first character.
Set up a hover provider to deal with hovers: This requires me once again to set up very specific data for each class/property/method (as with the first example), and ONLY does hovers, nothing else. (This is the least helpful example of the bunch, because it is doing a bunch of other things other than hovers, and contains no commentary.)
Use my class code to create a Model: This requires me to set up my code in a very readable way (e.g., if I want properties to be exposed, I need to set them up with explicit getters and setters), and requires me to do all of my documentation in JSDoc style comments, but will do hovers and autocompletion, not will NOT let me specify default values that will be injected on autocomplete (unless I've missed something).
Of the above, the last option seems easiest and best, because I already have the code, and all it requires me to do is annotate the comments in a very specific way, which is good practice anyway, and I also get some code validation through it. What I lose from it is the ability to do true autocompletion. Trying to combine all three approaches modes is made difficult both by the apparent fact that they require entirely different kinds of documentation (comments vs. providing a bunch of discrete properties; I am not that interested in doubling the amount of documentation I need to do, so it's really one or the other), and because they are probably incompatible in practice (I doubt the Model and Hover approach could be made to play nice with each other, for example).
So what I am asking here is: Am I missing something? Is this where this code base currently is at? I would love to be wrong here, and to be told, "oh, there's a way to use the Model approach that allows you to insert default code," but that doesn't seem to be the case. It is also very hard to use the Model code effectively with pure Javascript because it doesn't understand types (understandably) and it ignores my attempts to signal the expected types for various parameters through the JSDoc comments, but I'm not going to waste my time converting everything to TypeScript just to get around that issue.
I apologize if this is obvious but a lot of Googling has not turned up the answer, and the provided docs on Monaco Editor are terse to a point of uselessness, and the examples they provide are both themselves poorly documented and also somewhat useless by and large. I don't think what I am asking for is all that surprising (it is, from what I can tell from Googling, what most people who are thinking of integrating Monaco Editor into their applications or websites are looking for, because they are building little code editors that can be used with their own little language subsets) and yet it seems quite elusive to me.
Upvotes: 0
Views: 359
Reputation: 53502
This question description is pretty long, so it's difficult to answer in the Q&A fashion SO prefers. My understanding of it is that you want code completion, code hints and so one for JavaScript code the user enters in your editor control (based on Monaco), which uses library code that you provide, correct?
Monaco has full support for JS/TS/JSON built in. So, there's no need to implement any of providers (unless you want special behavior). However, you have to tell it what internal library you have that the user can use. This is usually done by adding a type definition to Monaco, which is then used by its built-in providers. The relevant API is addExtraLib
.
Upvotes: -1