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!
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
.
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...
- On function definitions, the return values are not properly formatted (not even recognised by Nova)
- Similarly, the
return
keyword will confuse the formatting of the ensuing expressions - 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) - Type declaration is still a work-in-progress; it's now foldable, but doesn't work correctly (getting it right is tough!)
- Even variable declaration is... sketchy, at best. Some instances of it work; most don't
- No type casting done (yet)
make
andappend
aren't done yet
- 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 thegopls
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! - 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!
- 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!). - 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.
- 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.
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.↩
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!