Nova

Extensions


Readme

Go Language Definition for Nova

An 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.

🙏 Thanks 🙏

My personal thanks to the major contributors of this project, without whom this extension would never been working:

Additionally, much of the more intricate and obscure issues have been solved by shamelessly copying code from:

Note: This is still an alpha version with reasonably working syntax highlighting and some extra goodies from using the Language Server Protocol, but it is plagued by unstability issues and frequent crashing. See below for some guidelines.

If nothing here works for you, you might try to use Spicer Matthews' own GoTools extension. The syntax highlighting should be about the same — 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.

In either case, additional Go specific features are available by installing the Go Language Server, gopls.

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 don't work quite right yet2.

Disclaimers

I'm a bit clueless about how the syntax highlighting engine/parser actually parses the language files. There is next-to-zero '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 the extraordinary (but sadly 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 complete, still had a lot of errors (basically he used the template for JavaScript), and, at the date of writing, was abandoned eight years ago. It still 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 at least some of the functionality to actually work. Most 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.

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.

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 tries to use the official (Google-supported) Go Language Server if you install it as described in the Installation section above.

This 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 others who travelled the same road and try to figure out how they've done it.

Note that Nova logs some language server interaction in the Extension Console, and if you run the 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 a bit cryptic.

In conclusion: all of the above is really 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

  1. Right now, the one that baffles us most is why we are getting Markdown from gopls but somehow Nova is confused and renders it as plain text (which is... weird). I think I managed to make gopls change from Markdown to plain text — so that Nova might at least display a simple one-liner, albeit unformatted.
  2. The extension crashes a lot, especially when in Development mode. There are no 'obvious' errors showing up on the console or the error logs, so this has been hard to track down (I suspect that there is some cleaning up that is missing). If you're plagued with these constant crashes, just uncheck the Enable Language Server checkbox on the Preferences for this extension. You will still get Go syntax highlighting, but the additional goodies provided by LSP will be turned off.
  3. 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 very near future... fingers crossed!

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 syntax is similar.

2 A notable example is that for some reason the Markdown emitted by gopls is not understood by the Nova editor, which is quite strange, since other LSPs (namely, @apexskier's TypeScript Extension) have no such problems.


Changelog

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)