Playdate-LuaCATS: VSCode autocomplete, types and inline Playdate SDK documentation

Hello all!

I'm excited to announce Playdate-LUACATS a complete set of types and comments for the PlaydateSDK. This is compatible with the Lua Language Server and VSCode Lua Extension (sumneko.lua) to support type checking, autocomplete and inline documentation in your IDE. LuaLSP supports VSCode, NeoVim and any editor with LSP support.

The format for these is LuaCATS Annotations (Lua Comment And Type System) but here's the meat: stub.lua.

Looking for testers and feedback. I've been using it for a while privately and caught some subtle bugs. in my own projects. One note: you may need to restart VSCode after installing the Lua VSCode Extension and editing your settings to point to the playdate-luacats library.


Previously:

15 Likes

This is excellent! I just added the extension and it's already been extremely helpful. It feels so nice to have proper completions on the API. Haven't run into any problems yet but I'll keep an eye out.

Thank you for creating and sharing this! Strong vote to include this in the SDK or at least in the extensions marketplace.

1 Like

Yeah, I hadn't actually considered publishing my own extension. Conceivably I could publish an extension that requires sumneko.lua with an auto-updating bundle of types. Or maybe piggy back on Orta.playdate.

I'm a relative novice with respect to vscode extensions and have found sumneko.lua to pretty opaque. It's written entirely in Lua, has been localized into multiple languages (en, pt-br, zh-tw, zh-cn) and uses a bunch of lua scripts at build time to generate JSON for the build artifacts (e.g. instead of package.json there's a lua script which programmatically generates a nested table which is then serialized). And those lua build scripts are not cross platform (windows-targeted).

I'm open to any suggestion of how to distribute updates to users -- right now it's "do a git pull on your local clone periodically? Which is a terrible strategy. For reference, you can see a list of releases or even subscribe to the Atom XML Feed like it's 2005.

Cool. I was already fleshing out my own definition files, but yours is much more complete.

With your settings.json I get a duplicate-set-field warning on

function playdate.update()
<code>
end

That can be suppressed by adding

"Lua.diagnostics.disable": [ "duplicate-set-field" ]

to it. Do you have another solution to that so I don't have to suppress all "duplicate-set-field" warnings?

workaround:

I've been giving the function a name and then assigning it later.
This works with other callbacks too:

local function update()
end

local function setup()
    playdate.update = update
    playdate.bButtonDown = function() print("B Button Pressed") end
end

alternatively ---@diagnostic {disable, disable-line, disable-next-line} rule

It's minimally documented but you can also disable rules for the current line, next line or entire file.
Just type ---@diagnostic in VSCode and the completions will guide you to:

---@diagnostic disable-next-line duplicate-set-field
function playdate.update() end

Potential fix:

Looks like Love2D declares their callback functions as aliases [link]:

---Callback function used to update the state of the game every frame.
---@alias love.update fun(dt: number)

Ours are done as function stubs [link].

Since there's a easy workaround, I'm not rushing to fix it or complain upstream. The workaround also encourages the creation of more modular code by hinting that callback can be altered at runtime so I'll take that as a win. :smiley:

1 Like

This is great! It works perfectly with neovim as well (just putting the settings in .luarc.json instead)

2 Likes

tldr: I've improved playdate-luacats types. git pull your local clone to get them.

I am excited to announce that I finally figured out how to do types for object.lua classes including extends(), super(), init() and the Object base class. You can see the changes here:

Also came up with a small workaround you may want to consider to explicitly show lua-language-server where a new class in the global namespace was created.

Instead of:

class('MySprite').extends(playdate.graphics.sprite)

Use:

MySprite = class('MySprite').extends(playdate.graphics.sprite) or MySprite

@abusch: Excited to hear it's working with NeoVim via .luarc.json! That's fucking awesome!

2 Likes

Just this morning I saw the properties warning when creating a new class and thought "I should pull the latest to see if this is fixed." :slight_smile:

Great work on this library! It's a massive improvement for me and I'm sharing it with anyone who will listen.

1 Like

Just commenting to say this is incredibly useful. Thank you so much for making this :slight_smile:

1 Like

I'm using this in Zed editor.

https://github.com/zed-industries/community/discussions/2332

I just add the stub.lua and .luarc.json to the top level of my project.
There might be a better way, but this was quick and easy for me.

It's surprising that Nova Playdate Extension doesn't have this capability @logan

1 Like

I'm afraid I'm not versed quite in what this would entail or how Lua works with this, since I'm not part of the Playdate team, but I'm sure they would be interested in trying to add it were it brought to their attention / filed! (Provided there are engineering cycles for it, of course, I can't myself say whether any of the team have seen this yet.)

1 Like

Also commenting to give love, thanks for this!!