lua-language-server icon indicating copy to clipboard operation
lua-language-server copied to clipboard

[Suggestion] Add ability to define an enum without using a table

Open mycroftjr opened this issue 1 year ago • 6 comments

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.

mycroftjr avatar Jun 19 '24 23:06 mycroftjr

Good capture, this is something that has also bothered me a lot, and I agree with this new type of annotations

MillhioreBT avatar Jun 19 '24 23:06 MillhioreBT

Implementing this requirement would be the same as supporting setfenv, which seems unlikely at the moment.

CppCXY avatar Jun 20 '24 06:06 CppCXY

Implementing this requirement would be the same as supporting setfenv

How so?

mycroftjr avatar Jun 20 '24 19:06 mycroftjr

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

A1steaksa avatar Sep 25 '24 17:09 A1steaksa

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)

Image

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.

TIMONz1535 avatar Jan 22 '25 15:01 TIMONz1535

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

tomlau10 avatar Jan 24 '25 15:01 tomlau10