wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
18.03k stars 807 forks source link

Lua type annotations #3132

Open kylechui opened 1 year ago

kylechui commented 1 year ago

Is your feature request related to a problem? Please describe. Seeing as Lua is a dynamically typed scripting language, it might be beneficial to include type annotations to provide autocomplete (to reduce typos), type-checking (to reduce other errors), and documentation in the editor itself.

Describe the solution you'd like Have the keys for the configuration table be annotated, so users of Lua LSP can enjoy a better configuration experience.

Describe alternatives you've considered The documentation on the website is very clear and helpful (in particular with having the default keys right there), but requires another window open to look back and forth between.

Additional context Seeing as the codebase is written almost entirely in Rust, I'm not sure how the annotations would work (since they're typically added in Lua files). Here's some screenshots illustrating what could be possible: image image image

wez commented 1 year ago

Relevant prior discussion: https://matrix.to/#/!PirwUBcuIlTXwNveYz:matrix.org/$Yiujl4grH4m7PllU0_lDDNr4-yoHywtotC3r1drmg1E?via=matrix.org&via=kde.org&via=envs.net

kylechui commented 1 year ago

Hmm it says that the link was malformed... do you mind trying to ping me on matrix? (still @kylechui)

chrisgrieser commented 1 year ago

I also support this. There are two projects I know of that add annotations (both by folke, actually)

  1. neodev.nvim (Adds annotations for nvim)
  2. Emmylua.spoon (Adds annotations for Hammerspoon)

While neodev uses annotations available in nvim's code, Emmylua takes a different approach and creates dummy files with empty functions and the the respective documentation added as luadoc above, for example in the file hs.application.lua

local M = {}
-- ...

-- Returns the filesystem path of the app.
--
-- Parameters:
--  * None
--
-- Returns:
--  * A string containing the filesystem path of the application or nil if the path could not be determined (e.g. if the application has terminated).
---@return string
function M:path() end

-- ...
return M

All the annotations are saved in a folder. That folder only has to be added as a workspace library either in the configuration for the lua lsp, or in a .luarc.json file (so the annotations are only available in the respective folder/workspace).

The approach of EmmyLua.spoon is quite straightforward and should be possible for WezTerm as well.

junkblocker commented 1 year ago

After trying to use https://github.com/nekowinston/wezterm-types ( @nekowinston ) , I realized I had to annotate the variables myself e.g.

---@type WezTermBlah
local wezterm = require "wezterm"

But then I found @jason0x43 's

https://github.com/jason0x43/dotfiles/tree/master/config/nvim/lua/user/types/wezterm

which did not require me to annotate the vars myself. Here are the changes that were needed for using it with nvim/lua_ls after extracting that folder at ~/dev/weztypes

diff --git a/.config/nvim/lua/plugins/lsp.lua b/.config/nvim/lua/plugins/lsp.lua
index f7a0c507..f1408995 100644
--- a/.config/nvim/lua/plugins/lsp.lua
+++ b/.config/nvim/lua/plugins/lsp.lua
@@ -103,6 +103,8 @@ local modules = {
             end

             local runtime_path = vim.split(package.path, ";")
+            table.insert(runtime_path, "?.lua")
+            table.insert(runtime_path, "?/init.lua")
             table.insert(runtime_path, "lua/?.lua")
             table.insert(runtime_path, "lua/?/init.lua")

@@ -182,6 +184,8 @@ local modules = {
                 -- For others, just run the inside content of the function
                 -- after this setup
                 ["lua_ls"] = function()
+                    local libs = vim.api.nvim_get_runtime_file("", true)
+                    table.insert(libs, vim.fn.expand("~/dev/weztypes"))
                     lspconfig.lua_ls.setup(vim.tbl_deep_extend("keep", config(), {
                         root_dir = function(...)
                             -- doing this so editorconfig based formatting happens instead of stylua based
@@ -202,7 +206,7 @@ local modules = {
                                 },
                                 workspace = {
                                     checkThirdParty = false, -- prevent luassert, luafilesystem, OpenResty annoyance
-                                    library = vim.api.nvim_get_runtime_file("", true),
+                                    library = libs,
                                     maxPreload = 100000,
                                     preloadFileSize = 10000,
                                 },

I see a mention of @wez saying on matrix that he can generate the types automatically from the source code. If so, supposedly this is the format that's most convenient acc. to this experiment.

chrisgrieser commented 6 months ago

Hmm, I tried various repos I could find for wezterm-types, and all of them are incomplete and/or outdated. The most complete one is justinsgithub/wezterm-types, though it is still lacking.

Due to the size and the ongoing pace of WezTerm development, I think auto-generating it from wezterm itself would be the way to go.

mikavilpas commented 6 months ago

TL;DR: have been looking at the same issue the last few weeks, and generating type annotations from the docs seems to be the easiest option for me too.

I have been looking for a good way to create lua language server type annotations from rust code myself. I don't think there is a ready solution available at the moment.

I actually started writing a rust implementation for the lua_ls type annotation system (only annotation/documentation generation) and proposed it as a solution in the yazi project here and here, but for now it looks like the discussion has stalled.

Even if my attempt were successful, I am not convinced it would be a good solution unless there is either

  1. significant buy-in from the project's developer team, or
  2. significant buy-in from mlua (the rust-lua bindings crate) team, which can be tracked e.g. here https://github.com/mlua-rs/mlua/issues/392. For example, automatically type checking the annotations based on the rust code would be a great addition.
wez commented 6 months ago

I think there are two parts to this:

The former either needs some support from mlua, or needs to employ something like the Api Definition stuff in eg: dropshot. dropshot is a REST API helper, rather than lua, but the concept and model could be applied to lua. The idea is that a proc macro with declarative attributes could be used to annotate the various functions and collect them together in a supplemental metadata struct. There could then be a wezterm subcommand that can emit that metadata in various forms. I think that this could be used to augment the docs as well.

The latter could leverage the existing ConfigMeta trait that is auto-derived for the main config struct: https://github.com/wez/wezterm/blob/b8f94c474ce48ac195b51c1aeacf41ae049b774e/config/src/config.rs#L51-L52 The same trait could be applied to more of the various types that are part of the API.

ZipingL commented 1 month ago

is this being developed