Nova

Extensions


Readme

Go Language Definition for Nova

An ongoing attempt to build a Go language definition for the Panic Nova editor, using the Language Server Protocol (LSP) with Google's official gopls language server for Go.

Note: v0.4.3 is still an alpha version with working syntax highlighting and extra goodies from using the Language Server Protocol, but it is plagued with some unstability issues, often leading to a crash. See below for some guidelines.

@jfieber added a 'Go' menu from which some functionality can be selected; in many cases, it will attempt to do a re-formatting according to Go's best practices, as well as organise imports. This is not working 100% of the time, though (and we still don't know why).

Worst case scenario: if nothing here works for you, you might try to use Spicer Matthews' own GoTools extension. The syntax highlighting should be similar — and that extension should not crash!

Installation

Once activated, files ending in *.go should automatically be recognised (and formatted) as Go language files. Similarly, *.tmpl Go template files will also be recognised1, and from version 0.4.0 onwards, even go.mod gets its own syntax highlighting.

Additional Go specific features are available by installing the Go Language Server, gopls. This will turn Nova into a quasi-IDE for Go!

If you use Homebrew to install your packages, all you need is to type:

brew install gopls

If not, you can install it as described here.

Then tick the Enable Language Server checkbox in the Preferences for this extension. If gopls is (correctly) installed in your search PATH, the extension should find it. If it is elsewhere, set that where in the Preferences for this extension as well. Note that Nova's language server support and gopls are both new and evolving. Many things may not work quite right yet.

When checking for syntax errors, gopls can optionally use https://staticcheck.io/ for additionally analysis; there is a checkbox on Preferences to allow the extra checking.

WARNING: (aye, again) If you click on Format/Organise Imports when saving file to get gopls to automatically reformat your code when saving, be warned: it really does corrupt the files! I'm not joking. The option is there just because I'm hoping to try it out until I find a way to fix the issue.

More information on the capabilities of gopls as well as its design/implementation considerations can be found on GitHub. As Nova gets better and better integration with Language Servers, and as Google also improves gopls to be more compliant with Microsoft's LSP definition, a lot of functionality will appear 'automagically' by simply upgrading Nova or gopls.

Disclaimers

I'm still a bit clueless about how the syntax highlighting engine/parser actually parses the language files (although some things are starting to make more sense). There is very little 'official' documentation; however, on the site for an editor made by a competitor, it looks like they have used something very similar, and — allegedly! — based on the original Coda syntax (not Coda 2!). Apparently, Nova uses a variant of the same parser 'family'.

This version includes a Go.xml Syntax template which was cobbled together out of a lot of sources, namely, the Coda 2 Go language definition files; the Nova (included) language files for PHP, TypeScript (because Go is also strongly typed), JavaScript, and even C++; I've made extensive use of https://regex101.com/ to check the correctness of most (if not all) regular expressions needed for the syntax highlighting; and I'm also very quite thankful for the (incomplete) work made by @ambelovsky (on GitHub), when adapting the old Coda syntax for the editor from the competition. Several of his comments have been copied and incorporated. His work was sadly not completed, still had a lot of errors (basically he used the template for JavaScript), and, at the date of writing, was abandoned nine years ago. Nevertheless, it had lots of very interesting structures to parse the Go language (while leaving several others unimplemented). While strongly inspired by his work, this is not merely a copy & paste — many adaptations were required to get some of the functionality to actually work. A lot still doesn't (it gets silently ignored) and I still haven't figured out how to deal with them...

Additionally, I've included a Syntax template for Go Templates. It's almost exactly the same as the syntax for Smarty templates (which I have been using) with some tiny changes, which I hope to have correctly implemented.

The new, incuded syntax highlighter for go.mod files was mostly an experiment. It works quite well, though, since the language definition for that is so simple.

Although the current version includes a Completions file, I don't see any kind of completion happening (except for closing braces). I've tried to figure out how the syntax of the Completions file works, but it's even more obscure (to me) than the actual Syntax file. The two are also possibly related — through common identifiers — but I fail to understand exactly how the two 'play' together. I've gotten access to a few more resources explaining this format, so maybe I'll give it another try.

Also, Nova — unlike Coda — allows extensions to use the Language Server Protocol (like their closest competitors do), a Microsoft-promoted effort enabling a 'write once, reuse often' philosophy for writers of syntax checkers. In other words, the hard work is put into creating a functioning LSP 'server' (basically an application that reads a file in a specific language, or parts of a file, and figures out if it has any syntax errors) by the community of syntax checkers. Then editor plugins (of all kinds, not only desktop apps) can interface with such a server in order to get syntax checking. In theory, it's a very easy way to quickly expand the ability for a code editor to accept gazillions of languages without requiring the developers to spend days and nights coding as many syntax checkers as possible. With new languages coming up all the time, many becoming fashionable for a few years and disappearing shortly afterwards, this method ensures that editor developers are not wasting their precious time. It also means that updating syntax checkers for upcoming new versions of a specific language will not require any coding — just upgrade the LSP server. And, finally, it also means that all code editors will check syntax in the same, predictable way (and also that all will get upgraded to the latest version of the syntax almost immediately), which means that, if you switch editors, the 'new' editor will already support the latest version of your favourite programming language and syntax checking will work in pretty much the same way...

Therefore, this extension can optionally use the official (Google-supported) Go Language Server if you install it as described in the Installation section above. Thanks to recent improvements in Nova, it's now almost fully functional. Enjoy 😌

The LSP specification is still very quirky. Microsoft developed the LSP specifically for Visual Studio Code, their free, open-source, cross-platform editor, thus allowing non-Microsoft-specific languages to be as easily integrated with their editor. However, the Microsoft specifications are very Microsoft-centric, and the Google team behind gopls grumbles and complains about several ambiguous descriptions in the protocol, and the choices they've made to implement the (complex) specifications. Sadly, though, those specifications are very Google-centric (notice the pattern?) and they don't match easily with the Microsoft ones. And on top of all that, we have to deal with Panic's own implementation of LSP support — which is (at the time of writing!) a bit obscure, a bit opaque, and not exactly super-well-documented (namely, at least for me, it's not obvious what Nova does on its own and what the extension developer has to do). We have to take hints from the very few others who travelled the same road and try to figure out how they've done it.

Note that Nova logs many interactions with the language server in the Extension Console, and if you run this extension in "developer mode" (see the Extension Development item in Nova's General preferences) gopls will write logs to /tmp/gopls.log but these can be quite a bit cryptic.

In conclusion: all of the above is still very much a work in progress — or rather, a lot of work in progress. There is far less functionality which actually does anything than lots of files with rules that are supposed to do something but... don't. Therefore, caveat utilitor.

Suggestions and bug reports are more than welcome, but please take into account that I'm new to all of this, and might not be able to even understand most of your issues, much less fix them! But I'm learning...

Well-known bugs

Syntax Checker bugs

  1. On function definitions, the return values are not properly formatted (not even recognised by Nova)
  2. Similarly, the return keyword will confuse the formatting of the ensuing expressions
  3. On function definitions, arguments such as (a,b integer) will be correctly formatted, but they are on the completely wrong scope (compare it with writing (a integer, b integer) instead)
  4. Type declaration is still a work-in-progress; it's now foldable, but doesn't work correctly (getting it right is tough!)
  5. Even variable declaration is... sketchy, at best. Some instances of it work; most don't
  6. No type casting done (yet)
  7. make and append aren't done yet

Go Language Server bugs

  1. Right now, the one issue that baffles me most is why the imports formatter does not work properly (i.e. the equivalent functionality to goimports which is allegedly built-in into the gopls Language Server)! It still has a very serious bug when figuring out what exactly to delete and shuffle around. Don't try it out without saving your files properly!
  2. As said before, do NOT turn on the automatic formatting when saving! Until this issue isn't fixed, that option is essentially there only for the purpose of allowing others to do some testing. It's not meant for anything else!
  3. The Go menu (either from the top bar or by right-clicking on the text) runs the formatter most of the time, without crashing. Sometimes it does nothing; sometimes you have to select the whole range you wish to format in order to get it working. This is still a bit unpredictable, although I can't understand why it doesn't work some times, while in most cases, it has no issue whatsoever (even on the same, unchanged code!).
  4. If you're plagued with extension crashes, just _un_check the Enable Language Server checkbox on the Preferences for this extension. You will still get Go syntax highlighting (and some auto-completion), but the additional goodies provided by LSP will be turned off.
  5. There are a few hooks allowing you to theoretically run some post-formatting tools to comply with Google's style guidelines for Go, as well as a way to check that all imports are properly referenced, etc. With this version, there is no documentation yet for how to activate those extra features, but hopefully this will be addressed in the future... eventually.

My GPG Fingerprint

In case you need it to send me encrypted emails:

CE8A 6006 B611 850F 1275 72BA D93E AA3D C4B3 E1CB

1 I based that parser on the PHP Smarty templates — Go's own template syntax is similar.

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Daniel Seripap💻 Matt Mc🤔 💬 John Fieber💻 🤔 📖 Cameron Little🤔

This project follows the all-contributors specification. Contributions of any kind welcome!


Changelog

Version 0.4.3

  • Several new improvements on syntax checking; a lot more is being correctly highlighted (but there is even more that isn't; see README.md).
  • Adding the @all-contributors GitHub bot to give people a bit more credit. They deserve it!
  • Edited some of the (outdated) information on the README.
  • Added a special class on my sister project, the Nord theme extension, to provide highlighting for delimiters.
  • More crazy tests on basictest.go to catch common syntax highlighting errors (there are many).
  • Added a funding button, let's see if it works!
  • TODO(gwyneth): Try to understand why the imports aren't properly formatted by gopls, even if the rest is...

Version 0.4.2

  • Thanks to @logan's changes on correctly implementing Markdown hover tags!

Version 0.4.1

Version 0.4.0

  • Nova 5.1 is out and it supports Language Servers much better! Enjoy the quasi-IDE environment!
  • Added support for editing go.mod files. Note: If you've installed VLC, .mod files are thought to be audio files, thus they're not easily opened with Nova (added Tests/go.mod.sample to test it out).
  • Big cleaning up of the syntax definition file; all regular expressions have been tested, one by one, and fixed in uncountable cases. Even capturing complex numbers works! Much better syntax highlighting. Incidentally, issue #1 got fixed, after 7 months...
  • The Editor > Go menu options for text formatting and reorganising imports work about 80% of the cases. They are now interfacing correctly with gopls and retrieving proper replacement information (who'd think that Google would send all updates in reverse order?!). So, no need to run any additional external commands for those operations; gopls is supposed to do all the work from now on.
  • Sadly, the option to format/optimise imports on saving is not functional. There is an experimental checkbox for it on the preferences, but DO. NOT. CHECK. IT.. It will literally destroy your files when saving them. Basically, it runs the formatter twice, for some unfathomable reason, and I couldn't find a way to prevent that.

To-do:

  • Add a checkbox to get your code additionally validated by https://staticcheck.io/. It's easy enough to set up — it's fully integrated by Google in gopls itself!
  • Make the new code to convert from Nova ranges into LSP ranges a bit more efficient; or pester Panic to do that conversion available via the JS API (after all, they use it internally!). Note that this is mostly a proof-of-concept version (it's still alpha code, remember? 😉) just to fix an annoying bug that comes from wrong assumptions about gopls (other Language Servers seem to work... all have their own quirks).
  • Figure out why gopls is running twice when saving (thus thrashing everything), although just once when called from the menu options. I've clearly hit a personal limit; this is beyond my ability and knowledge to understand at the moment.
  • Figure out how to install VLC and still have Nova opening go.mod files without thinking they're video files!

Version 0.3.5

  • Basically just bumping the version to remove the warning about not being possible to update this extension via the Nova Extension Library. Panic fixed everything!
  • Amazingly, the reorganisation of import files, via gopls, seems to work! 😲 Try to mouse-select your imports and click on Editor > Go > Organize Imports — this should do something
  • The extension still crashes if it is deactivated/reactivated; also, it now might get a bit confused when figuring out if the gopls server is running or not. Sometimes it requires a reset (via the check box on Preferences).

Version 0.3.4

  • Many of the crashes are related to objects which haven't been correctly initialised, or, worse, released (google for KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED); this release attempts to fix some of those errors
  • Added more try{...}catch constructs in order to see some (possibly hidden) errors before Nova crashes
  • Slightly changed a few functions to better deal with the differences in handling extensions with a Language Server, compared to earlier Nova versions

Version 0.3.3

  • Finally figured out how to turn hover Markdown off! Next step: figuring out how to fix it...
  • Banner logo is back, I thought it made a difference when downloading the extension, but no: the problem lies elsewhere on Nova's servers (as of writing, they're on it and trying to fix things)
  • Fixed a few extra things, again, to comply with the extension template
  • Tried to incorporate @jfieber's changes (a few options now appear on the Editor menu, but they don't do much; I know that they're working, since they do get gopls to write things on the log)
  • Updated license to display contributors (Nova won't show it, though)
  • Updated README with some extra thanks and a warning that downloading this extension/updating it may fail due to some as-yet-unsolved issues with Panic's Nova Extension Library server (this plugin is not the only one being affected)

Version 0.3.2

  • Changed some of the code to comply better with the latest extension template included with Nova 4.3 — this may, or may not, fix some crashing issues (because things were called differently before)
  • Force gopls to use plain text instead of Markdown, on a single line; it's not as nice, but at least it works
  • Apparently there was some issue with Nova's library extension server earlier on, and that's why the earlier version failed, it should get fixed sooner or later

Version 0.3.1

  • Bumping the version because something went wrong with the upload

Version 0.3.0

  • Major rewriting of the code base, mostly thanks to the generous work provided by @jfieber and @seripap. Thanks guys!
  • LSP interfacing with gopls now works! But don't expect miracles, we haven't still figured out all of it. Use brew install gopls.
  • A few extension preferences were added by @jfieber (namely, turning LSP on and off, etc.); also, for development purposes, gopls will write some (cryptic) logs under /tmp/gopls.log
  • Added more references to licenses; we are now including open-source code from Microsoft (I never though I'd ever write this in my lifetime! 😳🤓)
  • Added more blahblahblah to the README.md (and a few markdown tricks!)
  • New logo (ok, this is trivial, but I'm trying to keep up with Panic's re-styling! 😅)
  • To-do: figure out why gopls sends raw Markdown that Nova doesn't seem to understand
  • To-do: understand why the extension crashes so often (at least in dev mode); it's possible that some cleanup code is missing and/or broken
  • Tested under Nova 4.3

Version 0.2.1

  • Small JSON change from 'vendor' to 'organization' according to the new specs for the Nova Beta 1.0b18 (195066)
  • Tried to add gopls again, but couldn't

Version 0.2.0

  • Added gazillions of changes, based on several different templates and the manuals of a competitor editor which uses similar syntax (which was originally based on the templates for Coda!)
  • While this produces slightly better matching, there are tons of rules that never get activated but I don't know why
  • Added a Smarty-like parser for Go Templates (it's basically the same concept with some tiny, Go-specific changes)
  • Added some test files, please ignore them, they're not meant to be 'working code' (nor even valid one)
  • Had to remove gopls because it's too big! You can download it from https://github.com/golang/tools/tree/master/gopls

Version 0.1.6 (never released)

  • With the new Nova Beta update to 1.0b17 (Build 190148) it looks like the executable for gopls lost its executable flag; if that did make a difference or not is beyond me, but I recompiled gopls again, with newer libraries.
  • When clicking on the syntax inspector button (at the bottom of each pane, the tiny 'target' icon which is to the left of the 'current symbol'), now 'something' happens when randomly clicking on Go code (i.e. there is a modal popup box that shows some information). If that's the desired behaviour or not... I have no idea.

Version 0.1.5

  • Make .mod files (e.g. go.mod) be part of the extensions, or else they will be seen as music files

Version 0.1.4

Cleaning up the logs when instance is deactivated.

Version 0.1.3

  • Bumped version again
  • Some more experiments on the test file basictest.go

Version 0.1.2

  • Slight bug on main.js (missing bracket)

Version 0.1.1

  • Version 0.1.0 was successfully uploaded to the Extensions Library!!
  • Go LSP seems not to be working at all
  • Lots of errors in syntax highlighting (e.g. variable declaration)

Version 0.1.0

  • After checking the many XML files, I found three minor bugs, and now the syntax highlighting not only works, but it shows up as a 'valid' language on all the places that it ought to show up!
  • Apparently, you cannot have any images under the Images/ folder, or uploading to the Extension Library does not work
  • Still working to fix the connection to the Go LPS (it's not being launched right now, but I have some ideas to fix it...)

Version 0.0.2

  • Syntax definition XML based on Nova JavaScript, using definitions from the old Coda 2 Go mode
  • Tried to add Go LPS support
  • Added the logo and a few things

Version 0.0.1

Initial release — based on the original Coda 2 Go mode


License

MIT License

Copyright (c) 2020-2021 Gwyneth Llewelyn, John Fieber, Daniel Seripap

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Parts of the code may be subject to the Microsoft Public License (MS-PL)