Big update to prettier-extension-monkeyc

I've posted about prettier-extension-monkeyc before, but I've added a bunch of new features that developers will probably like (well, I've been missing them, so maybe you have too).

The new features it implements for VSCode include:

  • Goto Definition. Point at a symbol, Ctrl/Cmd click, and it will take you to the definition. Or F12
  • Goto References. Right click on a symbol and select "Goto References". It will show you all the references. Or Shift-F12
  • Peek Definition/Peek References. Same as above, but in a popup window so you don't lose your place in the original document.
  • Rename Symbol. Right click on a local, function, class or module name, and select "Rename Symbol". It will rename all the references. It doesn't yet work for class members/methods.
  • Goto Symbol. Type Ctrl/Cmd-Shift-O and pick a symbol from the drop down (which has a hierarchical view of all symbols in the current file). This also appears as an outline across the top of the file.
  • Open Symbol By Name. Type Ctrl/Cmd-T, then start typing letters from a symbol name. A drop down will be populated with all matching symbols from anywhere in your project.

Older features include a prettier based formatter for monkeyc, and a monkeyc optimizer that will build/run/export an optimized version of your project.

[edit: My last couple of replies seem to have just disappeared, and the whole conversation seems to be in a jumbled order, so tldr: there's a new test-release at https://github.com/markw65/prettier-extension-monkeyc/releases/tag/v2.0.9 which seems to work for me on linux. I'll do more verification tomorrow, and push a proper update to the vscode store once I'm sure everything is working]

  • If your mac is barely three times faster I won't ask how old it is

    It's 2019, so certainly not new. On the other hand, 3x seems pretty good for single threaded performance (due to limitations of javascript worker threads, I've not been able to use them to speed up the optimization step, so its currently all single threaded). A lot of the improvement in modern processors is just having more cores available - but that doesn't help here.

    Optimization step completed successfully in 6278ms

    Ok - so thats pretty much the same as your project.

    I've tried that one on an old windows machine, and I get 4800ms for the optimization time; so only a little faster than yours, but no sign of any editor slowdown.

    Then I remembered that you mentioned the vim extension... so I tried installing that, and sure enough, it becomes really sluggish. Even on my mac there are very noticeable delays. Not quite unusable, but I wouldn't /want/ to use it.

    I'm not quite sure what's going on, but I think it's because all the extensions share a single thread. So while my extension *is* blocking, I don't normally notice it. Its only when vim comes along and tries to handle all the keystrokes in the same thread that there's a problem.

    If thats the case, I may be able to fix it by simply adding more yield points; but a better solution would be to move the analysis into a worker thread. I don't think that should be too hard - but js worker threads tend to be unwieldy...

    For now, the new "Disable Analysis" setting does fix the sluggishness. Or you could turn vim off :-\

  • For now, the new "Disable Analysis" setting does fix the sluggishness. Or you could turn vim off :-\

    I've disabled the analysis, and I'm trying neovim because it's seems to be faster than the vim extension. It works a little differently so that will take some getting used to. It would be nice if I could do this in Linux but I haven't heard anything on that yet.

  • The documentation for the neovim extension mentions an "affinity" setting which runs the extension in its own thread.  Presumably, this makes the extension immune to *other* extensions blocking the main extension thread.  It appears to be a VSCode settings which can be applied to any extension, not just neovim.  So you might be able to enable it for the vim extension, too, if you don't want to switch.

  • It appears to be a VSCode settings which can be applied to any extension, not just neovim

    Oh nice. It's actually still an "experimental" feature. It seems like the best thing to do would be to turn it on for my extension:

    "extensions.experimental.affinity": { "markw65.prettier-extension-monkeyc": 1 }

    I've just tried it with vim installed, and it does fix the issue. But it seems to have a pretty adverse effect on the performance of the extension. So that eg it takes a long time for "hover" info to show up, and after making changes to the code, it takes a while for "Goto Definition" etc to start working. That's not nearly as bad as when it doesn't respond when you type - but I think I need a better solution.

    I suspect the issue is that as written, there's an enormous amount of data that needs to be shunted back and forth, and vscode has no choice but to just move all of it. If I use a worker thread, and refactor a little, I can keep almost everything in the worker thread, and just shunt the data thats actually needed back to the main thread.

    EDIT: Actually, I've been trying this again, and it seems to work perfectly. I think I was running tests in the background yesterday when I tried this, and it just happened that it got to a cpu intensive part of the tests when I was playing with the option.

  • Why not move the vim extension into a separate thread instead of moving your extension?  Since the vim extension is the only one that needs that really snappy latency to handle keystrokes?

  • Why not move the vim extension into a separate thread instead of moving your extension

    I guess do whatever works best... but its my extension thats causing the problems, and it could potentially interfere with *any* other extension.

  • I am getting a false positive warning:

    "This comparison seems redundant because smTick should never be null"

    typedef oneDim as Array<Double or Float or Number>;
    typedef twoDim as Array<oneDim>;
    
    	private var _smTicks = new [0] as Array<twoDim or oneDim or Null>?;
    	
    		public function ticksDraw(tickdc as Dc) as Void {
    	
    			var smTick = [] as oneDim;
    			for (var j = 1; j <= 59; j++) {
    				smTick = (_smTicks as twoDim)[j] as oneDim;
    				if (smTick != null) {
    					tickdc.drawLine(smTick[0], smTick[1], smTick[2], smTick[3]);
    				}
    			}
    	

    In _smTicks every fifth element is null, because that's where the _lgTicks are. To be clear, the code works fine. The seemingly excessive types are to resolve the compiler "cant determine type" warnings.

  • The warning looks correct to me.

    By inserting the cast (_smTicks as twoDim), you're asserting that none of its elements are null. If some of the elements are null, then either twoDim should be declared as Array<oneDim?>, or this cast should be (_smTicks as Array<oneDim?>). And even without that, the cast to oneDim (rather than oneDim?) asserts that it's not null.

    I think that "(_smTicks as Array<oneDim?>)[j]" is both exactly what you're trying to say here, and should be enough to keep Garmin's type checker, and my type checker happy...

    Also note that "new [0]" is just a very verbose way of saying "[]".

  • It does seem that it was the not allowing null that it was catching. As you said either of these work:

    smTick = (_smTicks as twoDim)[j] as oneDim?;
    
    smTick = (_smTicks as Array<oneDim?>)[j];
     
    By Occam's Razor the simpler answer is probably right.

    Maybe this one is trickier?

    		var lowPalette = [array of the named colors] as Array<ColorValue>;
    
    				var cPicBufOpts = {:width=>picX, :height=>picY, :bitmapResource=>_centerPic};
    				if (_isLowColor) {
    					cPicBufOpts.put(:colorDepth, 4);
    					cPicBufOpts.put(:palette, lowPalette);
    				}
    	

    WARNING> fenix7x: Argument 2 to $.Toybox.Lang.Dictionary.put expected to be Number or Toybox.WatchUi.BitmapResource<{getWidth: Function<Toybox.WatchUi.BitmapResource.getWidth>, getHeight: Function<Toybox.WatchUi.BitmapResource.getHeight>}> but got Array<Number as Toybox.Graphics.ColorValue>

    It looks like it's expecting new values being added to a dictionary to be the same type as other items already in the dictionary. Does a dictionary get typed when it's first assigned? Again, this code works on 4-bit color devices like my FR235.