Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type checking with Lua Language Server type annotations #119

Merged
merged 39 commits into from
Mar 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e2f203f
point Lua Language Server to the `main.lua` file
CogentRedTester Jan 15, 2025
dca80bb
Add initial type annotations for globals and common data types
CogentRedTester Jan 15, 2025
dea1b11
typing: change parser types to support addons
CogentRedTester Jan 15, 2025
fbc5afa
update .luarc.json with new settings
CogentRedTester Jan 16, 2025
4296fd8
github-actions: add initial linter workflow
CogentRedTester Feb 2, 2025
1fbf090
fb_utils: add type annotations for all functions
CogentRedTester Feb 2, 2025
2bc9f7d
fb_utils: fix typing for coroutine functions to take async functions
CogentRedTester Feb 2, 2025
e70a3a3
playlist.lua: add type annotations for all functions
CogentRedTester Feb 2, 2025
1c5a6f9
keybinds.lua: add type annotations for all functions
CogentRedTester Feb 3, 2025
5da0208
scanning.lua: add type annotations for all functions
CogentRedTester Feb 3, 2025
ec47710
script-messages.lua: add type annotations
CogentRedTester Feb 3, 2025
2ef5af0
ass.lua: add type annotations
CogentRedTester Feb 3, 2025
1da3c49
setup.lua: add type annotations
CogentRedTester Feb 3, 2025
7013ccd
cache.lua: add type anotations for function and cache
CogentRedTester Feb 3, 2025
4c3f697
controls.lua: add type annotations for functions
CogentRedTester Feb 3, 2025
2a22f60
observers.lua: add type annotations for functions
CogentRedTester Feb 3, 2025
d5e5d5d
addons.lua: add type annotations
CogentRedTester Feb 3, 2025
d528905
Merge branch 'master' into type-annotations
CogentRedTester Feb 22, 2025
83b79b9
add more types and classes to globals.lua and options.lua
CogentRedTester Feb 22, 2025
2613cb9
improve ParseState typing
CogentRedTester Feb 22, 2025
1be395a
add type annotations for fb and parser APIs
CogentRedTester Feb 22, 2025
716555f
fixed some addon and parser related types
CogentRedTester Feb 22, 2025
d25b68e
addons: add type annotations, fixing type errors where necessary
CogentRedTester Feb 22, 2025
ce5ba21
playlist.lua: no-longer store values in the List and Item tables
CogentRedTester Feb 22, 2025
d986d11
lint.yml: no-longer upload report artifacts
CogentRedTester Feb 22, 2025
453d979
address type warnings caused by Lua5.1 and 5.2 changes
CogentRedTester Feb 22, 2025
647c260
properly define classes for modules
CogentRedTester Feb 27, 2025
37aadfe
add definitions for mpv modules
CogentRedTester Feb 27, 2025
97cdd6b
update typing to fix errors from mp definitions
CogentRedTester Feb 27, 2025
04431b4
Merge branch 'master' into type-annotations
CogentRedTester Feb 27, 2025
1b2494c
fb.rescan: ensure the return value is not nil
CogentRedTester Feb 27, 2025
9116044
add definitions for mpv-user-input
CogentRedTester Feb 27, 2025
b30b53d
add mp.options defintiion
CogentRedTester Feb 27, 2025
dc5eac1
LuaLS: enable warnings for unknown types
CogentRedTester Feb 27, 2025
eac5262
improve typing for modules to resolve or allow unknown types
CogentRedTester Feb 27, 2025
17313c8
typing: add and modify types related to the mpv subprocess command
CogentRedTester Feb 27, 2025
a03c689
addons: update typings to resolve unknown types
CogentRedTester Feb 27, 2025
70085f5
windir: update typings to disable warnings about LuaJit modules
CogentRedTester Feb 27, 2025
dbad0f4
fix module path for api/fb.lua
CogentRedTester Mar 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# This is a basic workflow to help you get started with Actions

name: Lint

# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "master" branch
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
Build_LuaLS:
# The type of runner that the job will run on
runs-on: ubuntu-latest

outputs:
luals_version: ${{ steps.get-luaLS-version.outputs.version }}

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- name: Get LuaLS version
id: get-luaLS-version
run: |
version=$(curl https://api.github.com/repos/LuaLS/lua-language-server/releases/latest | jq -r '.tag_name')
echo $version
echo "version=$version" >> $GITHUB_OUTPUT
shell: bash

- name: Cache Lua Language Server
uses: actions/cache@v4
id: cache
with:
key: ${{ steps.get-luaLS-version.outputs.version }}
path: ./luals

- uses: actions/checkout@v4
if: steps.cache.outputs.cache-hit != 'true'
with:
repository: LuaLS/lua-language-server
ref: ${{ steps.get-luaLS-version.outputs.version }}
path: ./luals

# Runs a single command using the runners shell
- name: Install Lua Language Server
if: steps.cache.outputs.cache-hit != 'true'
working-directory: ./luals
run: |
echo Running Lua Language Server build script
sudo apt-get update
sudo apt-get -y install ninja-build
./make.sh

Lint_LuaJit:
needs: Build_LuaLS
runs-on: ubuntu-latest
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4
with:
path: ./file-browser
- name: Cache Lua Language Server
uses: actions/cache@v4
id: cache
with:
key: ${{ needs.Build_LuaLS.outputs.luals_version }}
path: ./luals
- name: Run LuaLS
run: |
jq '."runtime.version" = "LuaJIT"' ./file-browser/.luarc.json > tmp.json
mv tmp.json ./file-browser/.luarc.json
./luals/bin/lua-language-server --check=./file-browser

Lint_Lua51:
needs: Build_LuaLS
runs-on: ubuntu-latest
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4
with:
path: ./file-browser
- name: Cache Lua Language Server
uses: actions/cache@v4
id: cache
with:
key: ${{ needs.Build_LuaLS.outputs.luals_version }}
path: ./luals
- name: Run LuaLS
run: |
jq '."runtime.version" = "Lua 5.1"' ./file-browser/.luarc.json > tmp.json
mv tmp.json ./file-browser/.luarc.json
./luals/bin/lua-language-server --check=./file-browser

Lint_Lua52:
needs: Build_LuaLS
runs-on: ubuntu-latest
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4
with:
path: ./file-browser
- name: Cache Lua Language Server
uses: actions/cache@v4
id: cache
with:
key: ${{ needs.Build_LuaLS.outputs.luals_version }}
path: ./luals
- name: Run LuaLS
run: |
jq '."runtime.version" = "Lua 5.2"' ./file-browser/.luarc.json > tmp.json
mv tmp.json ./file-browser/.luarc.json
./luals/bin/lua-language-server --check=./file-browser
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.vscode
27 changes: 27 additions & 0 deletions .luarc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"runtime.version": "LuaJIT",
"runtime.path": [
"?.lua",
"?/init.lua",
"../../script-modules/?.lua"
],
"diagnostics.workspaceDelay": 1000,
"diagnostics.groupFileStatus": {
"await": "Any",
"luadoc": "Any",
"type-check": "Any",
"unbalanced": "Any",
"strong": "Any"
},
"diagnostics.groupSeverity": {
"await": "Warning",
"strong": "Warning"
},
"diagnostics.severity": {
"missing-return": "Error!",
"missing-return-value": "Error!",
"cast-type-mismatch": "Error!",
"assign-type-mismatch": "Error!",
"global-element": "Warning!"
}
}
26 changes: 19 additions & 7 deletions addons/apache-browser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ local fb = require "file-browser"

--decodes a URL address
--this piece of code was taken from: https://stackoverflow.com/questions/20405985/lua-decodeuri-luvit/20406960#20406960
---@type fun(s: string): string
local decodeURI
do
local char, gsub, tonumber = string.char, string.gsub, tonumber
Expand All @@ -20,22 +21,32 @@ do
end
end

---@type ParserConfig
local apache = {
priority = 80,
api_version = "1.1.0"
}

---@param name string
---@return boolean
function apache:can_parse(name)
return name:find("^https?://")
return name:find("^https?://") ~= nil
end

--send curl errors through the browser empty_text
function apache:send_error(str)
---Send curl errors through the browser empty_text.
---@param str string
---@return List
---@return Opts
local function send_error(str)
return {}, {empty_text = "curl error: "..str}
end

---@async
---@param args string[]
---@return MPVSubprocessResult
local function execute(args)
msg.trace(utils.to_string(args))
---@type boolean, MPVSubprocessResult
local _, cmd = fb.get_parse_state():yield(
mp.command_native_async({
name = "subprocess",
Expand All @@ -48,21 +59,22 @@ local function execute(args)
return cmd
end

---@async
function apache:parse(directory)
msg.verbose(directory)

local test = execute({"curl", "-k", "-l", "-I", directory})
local response = test.stdout:match("(%d%d%d [^\n\r]+)")
if test.stdout:match("Content%-Type: ([^\r\n/]+)") ~= "text" then return nil end
if response ~= "200 OK" then return self:send_error(response) end
if response ~= "200 OK" then return send_error(response) end

local html = execute({"curl", "-k", "-l", directory})
if html.status ~= 0 then return self:send_error(tostring(html.status))
if html.status ~= 0 then return send_error(tostring(html.status))
elseif not html.stdout:find("%[PARENTDIR%]") then return nil end

html = html.stdout
local html_body = html.stdout
local list = {}
for str in string.gmatch(html, "[^\r\n]+") do
for str in string.gmatch(html_body, "[^\r\n]+") do
local valid = true
if str:sub(1,4) ~= "<tr>" then valid = false end

Expand Down
56 changes: 37 additions & 19 deletions addons/favourites.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

local mp = require "mp"
local msg = require "mp.msg"
local utils = require "mp.utils"
local save_path = mp.command_native({"expand-path", "~~/script-opts/file_browser_favourites.txt"})

local fb = require 'file-browser'
local save_path = mp.command_native({"expand-path", "~~/script-opts/file_browser_favourites.txt"}) --[[@as string]]
do
local file = io.open(save_path, "a+")
if not file then
Expand All @@ -15,16 +16,24 @@ do
file:close()
end

local favourites = nil
---@type Item[]
local favourites = {}
local favourites_loaded = false

---@type ParserConfig
local favs = {
api_version = "1.4.0",
priority = 30,
cursor = 1
}

local use_virtual_directory = true

---@type table<string,string>
local full_paths = {}

---@param str string
---@return Item
local function create_favourite_object(str)
local item = {
type = str:sub(-1) == "/" and "dir" or "file",
Expand All @@ -36,34 +45,38 @@ local function create_favourite_object(str)
return item
end

---@param self Parser
function favs:setup()
self:register_root_item('Favourites/')
end

local function update_favourites()
favourites = {}

local file = io.open(save_path, "r")
if not file then return end

for str in file:lines() do
table.insert(favourites, create_favourite_object(str))
end
file:close()
favourites_loaded = true
end

function favs:can_parse(directory)
return directory:find("Favourites/") == 1
end

---@async
---@param self Parser
---@param directory string
---@return List?
---@return Opts?
function favs:parse(directory)
if not favourites then update_favourites() end
if not favourites_loaded then update_favourites() end
if directory == "Favourites/" then
local opts = {
filtered = true,
sorted = true
}
if self.cursor ~= 1 then opts.selected_index = self.cursor ; self.cursor = 1 end
return favourites, opts
end

Expand All @@ -76,6 +89,7 @@ function favs:parse(directory)
local list, opts = self:defer(full_path or "")

if not list then return nil end
opts = opts or {}
opts.id = self:get_id()
if opts.directory_label then
opts.directory_label = opts.directory_label:gsub(full_paths[name], "Favourites/"..name..'/')
Expand All @@ -94,10 +108,14 @@ function favs:parse(directory)

local list, opts = self:defer(path)
if not list then return nil end
opts = opts or {}
opts.directory = opts.directory or path
return list, opts
end

---@param path string
---@return integer?
---@return Item?
local function get_favourite(path)
for index, value in ipairs(favourites) do
if value.path == path then return index, value end
Expand All @@ -106,14 +124,14 @@ end

--update the browser with new contents of the file
local function update_browser()
if favs.get_directory():find("[fF]avourites/") then
if favs.get_directory():find("[fF]avourites/$") then
local cursor = favs.get_selected_index()
favs.rescan()
favs.set_selected_index(cursor)
favs.redraw()
if fb.get_directory():find("[fF]avourites/") then
if fb.get_directory():find("[fF]avourites/$") then
local cursor = fb.get_selected_index()
fb.rescan()
fb.set_selected_index(cursor)
fb.redraw()
else
favs.clear_cache()
fb.clear_cache()
end
end
end
Expand Down Expand Up @@ -154,7 +172,7 @@ local function move_favourite(path, direction)
end

local function toggle_favourite(cmd, state, co)
local path = favs.get_full_path(state.list[state.selected], state.directory)
local path = fb.get_full_path(state.list[state.selected], state.directory)

if state.directory:find("[fF]avourites/$") then remove_favourite(path)
else add_favourite(path) end
Expand All @@ -163,15 +181,15 @@ end

local function move_key(cmd, state, co)
if not state.directory:find("[fF]avourites/") then return false end
local path = favs.get_full_path(state.list[state.selected], state.directory)
local path = fb.get_full_path(state.list[state.selected], state.directory)

local cursor = favs.get_selected_index()
local cursor = fb.get_selected_index()
if cmd.name == favs:get_id().."/move_up" then
move_favourite(path, -1)
favs.set_selected_index(cursor-1)
fb.set_selected_index(cursor-1)
else
move_favourite(path, 1)
favs.set_selected_index(cursor+1)
fb.set_selected_index(cursor+1)
end
update_browser()
end
Expand Down
Loading