ScriptEditor, First Impressions, Ideas, and Improvements

Hello

Usually, I am not a big fan of code editors integrated into software, but I have to admit that you have managed to create an editor that integrates perfectly with all the languages and specificities of Rhino development.

But of course, I have some things to say! :slight_smile:

Since Rhino 6, I have had my own C# compilation system, which is a makeshift setup with lots of bugs, and I am very happy that it can be replaced by the new ScriptEditor. However, it has some advantages that I would like to see implemented in this new system.

Editor

First of all, the editor itself, there are a few features that I sorely miss in ScriptEditor:

  • Zoom Wheel
  • Custom shortcuts for FoldAll and UnFoldAll (the default keyboard shortcuts of MonacoEditor have never worked for me, so I don’t even know if you have left them active or not)
  • The play button does not execute the file on the right when we simply click in the explorer.
    I always get caught, it would seem logical to me that the play button executes the displayed file.

Language

Next, without going as far as the full features of OmnisCharp:

  • It would be nice if tooltips displayed function arguments when opening a parenthesis or when the mouse hovers over a function name.
  • And since I tend to section my code into many small functions, I use the Ctrl+Click combination a lot to jump from one function to another.

API

  • Add callback functions to the Script_Instance class before each recompilation and when the Grasshopper document changes.
    In this example, the mouse listener is therefore a static object unique to each compilation that is cleaned up before each recompilation or disabled when the document changes.

  • Ability to define custom script options, i.e., static variables that are not directly related to the component’s result calculation. For example, debugging variables or, in this example, a variable allowing a visual aid to be displayed. These are variables that do not directly impact the result, and to avoid overloading the input parameters or the context menu, I have grouped them in a separate window.


File Explorer

  • Allow adding, moving, or renaming files in the explorer.
    Well, maybe that’s not a small task. But the file explorer in ScriptEditor is great, and it’s quite frustrating not being able to manage your code library directly in the interface.

jmv

1 Like

@kitjmv

  • Zoom Wheel :point_right: RH-81010
  • Fold Shortcuts :point_right: RH-78882
  • Function arguments on parenthesis open, or hover: This should already be working. Send me an example of a case that is not working for you and we will get that fixed.

Screenshot 2024-09-29 at 8.27.47 AMScreenshot 2024-09-29 at 8.28.04 AM

  • Ctrl+Click to jump to functions: Good idea :point_right: RH-84032
  • OnScriptExpired, and OnDocumentChanged event handlers? Let me think about this more. It would help if you can send me a specific example of why this is useful and how you are using it.
  • Custom script options: This sounds complicated as it requires building a UI from a set of options provided by the script. I will look into allowing scripts to add menu items to the script component context menu so they can build whatever options they want. :point_right: RH-84115
  • Add, move, rename in explorer: The file explorer button already support adding and removing. I need to make move operations better :point_right: RH-76941

3 Likes

Hello @eirannejad

about:

I think the example of bone manipulation is the most illustrative.
Here, several elements that require a subscription are necessary to make this demo work:
MouseCallback class, DisplayConduit class, Command.BeginCommand event, and Command.EndCommand event

MouseCallback

Allows capturing mouse inputs to move the blue circles.
To avoid capturing mouse inputs as many times as there have been compilations, the MouseCallback must be deactivated before recompilation and then activated after the new DLL file is generated.

To draw a parallel between the code present in the video below and ScriptEditor, we can consider that the code is in Script Mode (I actually use the CSX syntax) and I connect the inputs, outputs, and callback functions with attributes [Input], [Output], [OnContext], and [OnUnload].

The OnContext function is called by GH_Component.DocumentContextChanged(GH_Document document, GH_DocumentContext context) and receives the parameter GH_DocumentContext context, which allows managing all the Load/Unload, Open/Close, Lock/Unlock scenarios.

The OnUnload function, on the other hand, is called before all instances of objects created by the script are cleaned up and a new DLL file is generated and loaded into the component. (Since static variables are created only once, I did not need to implement an OnLoad function).

These two functions are called only once for each component, regardless of the number of parameters and their accessibility.

It should be noted that it would be useful to add the GotFocus and LostFocus scenarios to the OnContext function in case the Rhino window take or loses focus. I find this is a missing feature in the Timer component of Grasshopper. If you open your email to reply to a message, the script continues to run, which can be useful in some cases but not in all.

DisplayConduit

Displays the blue points, the purple curve, and the orange outline of the active sphere in the image below:
image

This object must also be properly deactivated to avoid drawing multiple times per viewport frame.

It would have been possible to use the Grasshopper CustomPreview component. However, the purple curve and the orange outline are displayed only if the mouse is over the sphere, so it is more practical and efficient to use a DisplayConduit directly.

Command.BeginCommand and Command.EndCommand

These two functions allow activating or deactivating the MouseCallback and the DisplayConduit while a Rhino command is executed, for example, Save.
Again, these events must be unsubscribed before each recompilation and re-subscribed with the functions of the newly generated DLL.


I hope I have been clear and precise enough, and I will answer your other questions gradually with other messages.


While searching the forum, I came across this thread which is apparently a revival from 2014 of the old Grasshopper site:


about:


That’s also what I had to do, but let’s keep it simple. Personally, I have only implemented 4 types: boolean, int, double, and string.
To be honest, I mostly use the boolean type, sometimes a number, and quite rarely a text option. I had wanted to implement Enum and Color, but in the end, I never felt the need for them.

This is also a possibility I had considered, but these script options are generally values that do not need to be constantly modified by the user. For example, Show logs for debugging or Refresh rate to update the 3D view (which would be a parameter more specific to the machine running Rhino).
I found it more practical and cleaner to group these custom options in a separate window, but in fact, both options do the same thing.

Hello @eirannejad

Indeed, it works… I don’t know what mistake I made… :face_with_diagonal_mouth:

1 Like

RH-84115 is fixed in Rhino 8 Service Release 13 Release Candidate

@eirannejad did you see?

@eirannejad Are you intentionally ignoring me?
There was no need to ask me for more details…