lua-language-server
lua-language-server copied to clipboard
[Suggestion] Add ability to define an enum without using a table
How are you using the lua-language-server?
Visual Studio Code Extension (sumneko.lua)
Which OS are you using?
Windows
What is the issue affecting?
Annotations, Type Checking, Completion
Suggestion
For existing codebases where enums are defined like this:
OPERATING_SYSTEM_WINDOWS = 1
OPERATING_SYSTEM_MAC = 2
KEY_A = 1
KEY_B = 2
it would be nice to be able to define all lines that follow (until the next blank line) as part of an enum without changing anything by introducing a table: i.e.
@enum OPERATING_SYSTEM
OPERATING_SYSTEM_WINDOWS = 1
OPERATING_SYSTEM_MAC = 2
@enum KEY
KEY_A = 1
KEY_B = 2
This would be convenient for type annotating when the values are passed as parameters and what-not. I'm not able to find any existing ways to designate these values as a "group" (or union) that maintains their use as global constants.
Good capture, this is something that has also bothered me a lot, and I agree with this new type of annotations
Implementing this requirement would be the same as supporting setfenv, which seems unlikely at the moment.
Implementing this requirement would be the same as supporting setfenv
How so?
This functionality would be very helpful to me. This is one of the few areas where LuaLS feels like it's missing an obvious feature
I'll duplicate the message from https://github.com/luttje/glua-api-snippets/issues/71#issuecomment-2607235098 here so that people can use it
Perhaps the word "enum" is confusing people. Initially, aliases were like an enums to describe the function args, that are usually not real variables (like io.open
openmode).You can also use it to create an enum that does not exist at runtime. For an enum that does exist at runtime, see
@enum.But then enum appeared for working with real tables that you create in your code.
Mark a Lua table as an enum, giving it similar functionality to
@alias, only the table is still usable at runtime.So when you want to make an enumeration of global constants, you need to make an alias. To display variables instead of values, you can use a literal. In fact, you can use any text or code here
---@alias Literal `MyReal.Thing[1]("str")`it will simply be inserted into the auto-completion.
ACT_INVALID = -1 ACT_RESET = 0 ACT_IDLE = 1 ACT_TRANSITION = 2 ACT_COVER = 3 ACT_COVER_MED = 4 ACT_COVER_LOW = 5 ACT_WALK = 6 ... ---@alias ACT ---| `ACT_INVALID` ---| `ACT_RESET` ---| `ACT_IDLE` ---| `ACT_TRANSITION` ---| `ACT_COVER` ---| `ACT_COVER_MED` ---| `ACT_COVER_LOW` ---| `ACT_WALK` ---| `ACT_WALK_AIM` ---|>`ACT_WALK_CROUCH` ---|+`ACT_WALK_CROUCH_AIM` ---| `ACT_RUN` ---| `ACT_RUN_AIM` ... ---@param a ACT function f(a) end f(ACT_RUN)
There is also a default modifier
|>and an additional modifier|+, but it doesn't seem to affect anything other than the visual marker.https://github.com/LuaLS/lua-language-server/blob/5275a75851207d6d871bc78ce2c9b42ad564ca7d/script/parser/luadoc.lua#L874-L893
https://github.com/LuaLS/lua-language-server/blob/5275a75851207d6d871bc78ce2c9b42ad564ca7d/script/core/hover/description.lua#L262-L267
It is uncomfy that it unfolds to multiple values in the hover display (rip ACT functions). In this regard, I would like to see only a title ACT like with enum's.
So when you want to make an enumeration of global constants, you need to make an alias. To display variables instead of values, you can use a literal. In fact, you can use any text or code here
---@alias Literal `MyReal.Thing[1]("str")`
I want to add that when using backtick literal in an alias, though it works for the auto completion, currently no param type check is performed
ACT_INVALID = -1
ACT_RESET = 0
ACT_IDLE = 1
INVALID_PARAM = ""
---@alias ACT
---| `ACT_INVALID`
---| `ACT_RESET`
---| `ACT_IDLE`
---@param a ACT
local function f(a) end
f(INVALID_PARAM) -- no warning, though `f` is marked to accept the `ACT` alias type