From 372ecdd403dfe926ff0620f8ab08dec4807c0ba9 Mon Sep 17 00:00:00 2001 From: Mika Vilpas Date: Wed, 1 May 2024 13:27:20 +0300 Subject: [PATCH] feat(lua): add basic LuaCATS types for internal lua code This commit adds rudimentary types for the internal lua code. This does not have a big effect on its own, but it can be a part of a bigger effort to add types to the codebase. The types are only usable within yazi itself and are not published for plugin developers to use (yet). I only added types for the things that are defined in the lua side of the codebase. This means most of the useful typing is still missing. I want to add that separately, as it would be difficult to keep the types in sync with the actual codebase. --- yazi-plugin/preset/components/current.lua | 6 +++++ yazi-plugin/preset/components/file.lua | 15 +++++++++++ yazi-plugin/preset/components/folder.lua | 7 ++++++ yazi-plugin/preset/components/header.lua | 10 ++++++++ yazi-plugin/preset/components/manager.lua | 5 ++++ yazi-plugin/preset/components/parent.lua | 3 +++ yazi-plugin/preset/components/preview.lua | 3 +++ yazi-plugin/preset/components/progress.lua | 5 ++++ yazi-plugin/preset/components/status.lua | 10 ++++++++ yazi-plugin/preset/plugins/archive.lua | 2 ++ yazi-plugin/preset/plugins/code.lua | 2 ++ yazi-plugin/preset/plugins/dds.lua | 1 + yazi-plugin/preset/plugins/file.lua | 2 ++ yazi-plugin/preset/plugins/folder.lua | 2 ++ yazi-plugin/preset/plugins/fzf.lua | 2 ++ yazi-plugin/preset/plugins/image.lua | 3 +++ yazi-plugin/preset/plugins/json.lua | 3 +++ yazi-plugin/preset/plugins/mime.lua | 3 +++ yazi-plugin/preset/plugins/noop.lua | 1 + yazi-plugin/preset/plugins/pdf.lua | 3 +++ yazi-plugin/preset/plugins/session.lua | 1 + yazi-plugin/preset/plugins/video.lua | 3 +++ yazi-plugin/preset/plugins/zoxide.lua | 7 ++++++ yazi-plugin/preset/types.lua | 13 ++++++++++ yazi-plugin/preset/ya.lua | 29 ++++++++++++++++++++-- 25 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 yazi-plugin/preset/types.lua diff --git a/yazi-plugin/preset/components/current.lua b/yazi-plugin/preset/components/current.lua index 5916ef1b7..391f6bf83 100644 --- a/yazi-plugin/preset/components/current.lua +++ b/yazi-plugin/preset/components/current.lua @@ -1,7 +1,11 @@ +---@class yazi.Current +---@field area? unknown Current = { area = ui.Rect.default, } +---@param area unknown +---@return table function Current:empty(area) local folder = Folder:by_kind(Folder.CURRENT) @@ -17,6 +21,8 @@ function Current:empty(area) } end +---@param area unknown +---@return table function Current:render(area) self.area = area diff --git a/yazi-plugin/preset/components/file.lua b/yazi-plugin/preset/components/file.lua index 1e7cabd20..a1b4b811b 100644 --- a/yazi-plugin/preset/components/file.lua +++ b/yazi-plugin/preset/components/file.lua @@ -1,5 +1,8 @@ +---@class yazi.File File = {} +---@param file unknown +---@return table function File:icon(file) local icon = file:icon() if not icon then @@ -11,11 +14,15 @@ function File:icon(file) end end +---@param file unknown +---@return table function File:prefix(file) local prefix = file:prefix() or "" return prefix == "" and {} or { ui.Span(prefix .. "/") } end +---@param file unknown +---@return table function File:highlights(file) local name = file.name:gsub("\r", "?", 1) local highlights = file:highlights() @@ -53,6 +60,8 @@ function File:found(file) } end +---@param file unknown +---@return table function File:symlink(file) if not MANAGER.show_symlink then return {} @@ -62,6 +71,8 @@ function File:symlink(file) return to and { ui.Span(" -> " .. tostring(to)):italic() } or {} end +---@param file unknown +---@return table function File:full(file) return ya.flat { self:icon(file), @@ -72,6 +83,8 @@ function File:full(file) } end +---@param file unknown +---@return table function File:style(file) local style = file:style() if not file:is_hovered() then @@ -83,6 +96,8 @@ function File:style(file) end end +---@param file unknown +---@return 0 | 1 | 2 | 3 | 4 function File:marker(file) local yanked = file:is_yanked() if yanked ~= 0 then diff --git a/yazi-plugin/preset/components/folder.lua b/yazi-plugin/preset/components/folder.lua index aaaa7df59..7affb761f 100644 --- a/yazi-plugin/preset/components/folder.lua +++ b/yazi-plugin/preset/components/folder.lua @@ -1,9 +1,12 @@ +---@class yazi.Folder Folder = { PARENT = 0, CURRENT = 1, PREVIEW = 2, } +---@param area unknown +---@param files unknown[] function Folder:linemode(area, files) local mode = cx.active.conf.linemode if mode == "none" then @@ -29,6 +32,9 @@ function Folder:linemode(area, files) return ui.Paragraph(area, lines):align(ui.Paragraph.RIGHT) end +---@param area unknown +---@param markers unknown[] +---@return table function Folder:markers(area, markers) if #markers == 0 or area.w * area.h == 0 then return {} @@ -73,6 +79,7 @@ function Folder:markers(area, markers) return elements end +---@param kind yazi.FolderType function Folder:by_kind(kind) if kind == self.PARENT then return cx.active.parent diff --git a/yazi-plugin/preset/components/header.lua b/yazi-plugin/preset/components/header.lua index 72cffa03b..a1246f532 100644 --- a/yazi-plugin/preset/components/header.lua +++ b/yazi-plugin/preset/components/header.lua @@ -1,7 +1,10 @@ +---@class yazi.Header Header = { area = ui.Rect.default, } +---@param max integer +---@return table function Header:cwd(max) local cwd = cx.active.current.cwd local readable = ya.readable_path(tostring(cwd)) @@ -10,6 +13,7 @@ function Header:cwd(max) return ui.Span(ya.truncate(text, { max = max, rtl = true })):style(THEME.manager.cwd) end +---@return table function Header:count() local yanked = #cx.yanked @@ -35,6 +39,7 @@ function Header:count() } end +---@return table function Header:tabs() local tabs = #cx.tabs if tabs == 1 then @@ -57,6 +62,9 @@ function Header:tabs() end -- TODO: remove this function after v0.2.5 release +-- +---@param area unknown +---@return table function Header:layout(area) if not ya.deprecated_header_layout then ya.deprecated_header_layout = true @@ -76,6 +84,8 @@ function Header:layout(area) :split(area) end +---@param area unknown +---@return table function Header:render(area) self.area = area diff --git a/yazi-plugin/preset/components/manager.lua b/yazi-plugin/preset/components/manager.lua index 72633ada9..f4868a8cd 100644 --- a/yazi-plugin/preset/components/manager.lua +++ b/yazi-plugin/preset/components/manager.lua @@ -1,7 +1,10 @@ +---@class yazi.Manager Manager = { area = ui.Rect.default, } +---@param area unknown +---@return unknown[] function Manager:layout(area) self.area = area @@ -15,6 +18,8 @@ function Manager:layout(area) :split(area) end +---@param area unknown +---@return unknown[] function Manager:render(area) local chunks = self:layout(area) diff --git a/yazi-plugin/preset/components/parent.lua b/yazi-plugin/preset/components/parent.lua index 8d76f77f6..acb45daf3 100644 --- a/yazi-plugin/preset/components/parent.lua +++ b/yazi-plugin/preset/components/parent.lua @@ -1,7 +1,10 @@ +---@class yazi.Parent Parent = { area = ui.Rect.default, } +---@param area unknown +---@return table function Parent:render(area) self.area = area diff --git a/yazi-plugin/preset/components/preview.lua b/yazi-plugin/preset/components/preview.lua index dd6b73cce..3eb672e99 100644 --- a/yazi-plugin/preset/components/preview.lua +++ b/yazi-plugin/preset/components/preview.lua @@ -1,7 +1,10 @@ +---@class yazi.Preview Preview = { area = ui.Rect.default, } +---@param area unknown +---@return table function Preview:render(area) self.area = area return {} diff --git a/yazi-plugin/preset/components/progress.lua b/yazi-plugin/preset/components/progress.lua index 079a445ed..8631f9d59 100644 --- a/yazi-plugin/preset/components/progress.lua +++ b/yazi-plugin/preset/components/progress.lua @@ -1,7 +1,11 @@ +---@class yazi.Progress Progress = { area = ui.Rect.default, } +---@param area unknown +---@param offset integer +---@return table function Progress:render(area, offset) self.area = ui.Rect { x = math.max(0, area.w - offset - 21), @@ -18,6 +22,7 @@ end -- -- However, at this time, we can only access `cx.tasks`. If you need certain data from the complete `cx`, -- just cache it to `self` during `render()`, and read it in `partial_render()` - this process is referred to as "composition". +---@return table function Progress:partial_render() local progress = cx.tasks.progress if progress.total == 0 then diff --git a/yazi-plugin/preset/components/status.lua b/yazi-plugin/preset/components/status.lua index de3d40149..c6aa25e57 100644 --- a/yazi-plugin/preset/components/status.lua +++ b/yazi-plugin/preset/components/status.lua @@ -1,7 +1,9 @@ +---@class yazi.Status Status = { area = ui.Rect.default, } +---@return unknown function Status.style() if cx.active.mode.is_select then return THEME.status.mode_select @@ -12,6 +14,7 @@ function Status.style() end end +---@return table function Status:mode() local mode = tostring(cx.active.mode):upper() if mode == "UNSET" then @@ -25,6 +28,7 @@ function Status:mode() } end +---@return table function Status:size() local h = cx.active.current.hovered if not h then @@ -38,6 +42,7 @@ function Status:size() } end +---@return table function Status:name() local h = cx.active.current.hovered if not h then @@ -47,6 +52,7 @@ function Status:name() return ui.Span(" " .. h.name) end +---@return table function Status:permissions() local h = cx.active.current.hovered if not h then @@ -76,6 +82,7 @@ function Status:permissions() return ui.Line(spans) end +---@return table function Status:percentage() local percent = 0 local cursor = cx.active.current.cursor @@ -99,6 +106,7 @@ function Status:percentage() } end +---@return table function Status:position() local cursor = cx.active.current.cursor local length = #cx.active.current.files @@ -110,6 +118,8 @@ function Status:position() } end +---@param area unknown +---@return table function Status:render(area) self.area = area diff --git a/yazi-plugin/preset/plugins/archive.lua b/yazi-plugin/preset/plugins/archive.lua index e53a7925e..225efc642 100644 --- a/yazi-plugin/preset/plugins/archive.lua +++ b/yazi-plugin/preset/plugins/archive.lua @@ -1,5 +1,6 @@ local M = {} +---@return nil function M:peek() local _, bound = ya.preview_archive(self) if bound then @@ -7,6 +8,7 @@ function M:peek() end end +---@param units number function M:seek(units) local h = cx.active.current.hovered if h and h.url == self.file.url then diff --git a/yazi-plugin/preset/plugins/code.lua b/yazi-plugin/preset/plugins/code.lua index f8c8e930c..d710352f6 100644 --- a/yazi-plugin/preset/plugins/code.lua +++ b/yazi-plugin/preset/plugins/code.lua @@ -1,5 +1,6 @@ local M = {} +---@return nil function M:peek() local _, bound = ya.preview_code(self) if bound then @@ -7,6 +8,7 @@ function M:peek() end end +---@param units number function M:seek(units) local h = cx.active.current.hovered if h and h.url == self.file.url then diff --git a/yazi-plugin/preset/plugins/dds.lua b/yazi-plugin/preset/plugins/dds.lua index b8a0452fc..d6b80b810 100644 --- a/yazi-plugin/preset/plugins/dds.lua +++ b/yazi-plugin/preset/plugins/dds.lua @@ -1,5 +1,6 @@ local M = {} +---@return nil function M:setup() ps.sub_remote("dds-cd", function(url) ya.manager_emit("cd", { url }) end) end diff --git a/yazi-plugin/preset/plugins/file.lua b/yazi-plugin/preset/plugins/file.lua index 6f331b4bc..80a85d5f1 100644 --- a/yazi-plugin/preset/plugins/file.lua +++ b/yazi-plugin/preset/plugins/file.lua @@ -1,5 +1,6 @@ local M = {} +---@return nil function M:peek() local cmd = os.getenv("YAZI_FILE_ONE") or "file" local output, code = Command(cmd):args({ "-bL", tostring(self.file.url) }):stdout(Command.PIPED):output() @@ -16,6 +17,7 @@ function M:peek() ya.preview_widgets(self, { p:wrap(ui.Paragraph.WRAP) }) end +---@return nil function M:seek() end return M diff --git a/yazi-plugin/preset/plugins/folder.lua b/yazi-plugin/preset/plugins/folder.lua index bac2a4f2f..6bdcf24b4 100644 --- a/yazi-plugin/preset/plugins/folder.lua +++ b/yazi-plugin/preset/plugins/folder.lua @@ -1,5 +1,6 @@ local M = {} +---@return nil function M:peek() local folder = Folder:by_kind(Folder.PREVIEW) if not folder or folder.cwd ~= self.file.url then @@ -38,6 +39,7 @@ function M:peek() ) end +---@return nil function M:seek(units) local folder = Folder:by_kind(Folder.PREVIEW) if folder and folder.cwd == self.file.url then diff --git a/yazi-plugin/preset/plugins/fzf.lua b/yazi-plugin/preset/plugins/fzf.lua index 210bd419f..239d41fc9 100644 --- a/yazi-plugin/preset/plugins/fzf.lua +++ b/yazi-plugin/preset/plugins/fzf.lua @@ -1,7 +1,9 @@ local state = ya.sync(function() return cx.active.current.cwd end) +---@return nil local function fail(s, ...) ya.notify { title = "Fzf", content = string.format(s, ...), timeout = 5, level = "error" } end +---@return nil local function entry() local _permit = ya.hide() local cwd = tostring(state()) diff --git a/yazi-plugin/preset/plugins/image.lua b/yazi-plugin/preset/plugins/image.lua index 1a6a7707c..120ef4dfe 100644 --- a/yazi-plugin/preset/plugins/image.lua +++ b/yazi-plugin/preset/plugins/image.lua @@ -1,5 +1,6 @@ local M = {} +---@return nil function M:peek() local url = ya.file_cache(self) if not url or not fs.cha(url) then @@ -10,8 +11,10 @@ function M:peek() ya.preview_widgets(self, {}) end +---@return nil function M:seek() end +---@return yazi.PreloaderReturnValue function M:preload() local cache = ya.file_cache(self) if not cache or fs.cha(cache) then diff --git a/yazi-plugin/preset/plugins/json.lua b/yazi-plugin/preset/plugins/json.lua index bca3ebb56..d991b0c83 100644 --- a/yazi-plugin/preset/plugins/json.lua +++ b/yazi-plugin/preset/plugins/json.lua @@ -1,5 +1,6 @@ local M = {} +---@return nil function M:peek() local child = Command("jq") :args({ @@ -41,6 +42,7 @@ function M:peek() end end +---@return nil function M:seek(units) local h = cx.active.current.hovered if h and h.url == self.file.url then @@ -52,6 +54,7 @@ function M:seek(units) end end +---@return nil function M:fallback_to_builtin() local _, bound = ya.preview_code(self) if bound then diff --git a/yazi-plugin/preset/plugins/mime.lua b/yazi-plugin/preset/plugins/mime.lua index 334169658..64d90fc63 100644 --- a/yazi-plugin/preset/plugins/mime.lua +++ b/yazi-plugin/preset/plugins/mime.lua @@ -2,6 +2,8 @@ local SUPPORTED_TYPES = "application/audio/biosig/chemical/font/image/inode/mess local M = {} +---@param s string +---@return string | nil local function match_mimetype(s) local type, sub = s:match("([-a-z]+/)([+-.a-zA-Z0-9]+)%s*$") if type and sub and string.find(SUPPORTED_TYPES, type, 1, true) then @@ -9,6 +11,7 @@ local function match_mimetype(s) end end +---@return yazi.PreloaderReturnValue function M:preload() local urls = {} for _, file in ipairs(self.files) do diff --git a/yazi-plugin/preset/plugins/noop.lua b/yazi-plugin/preset/plugins/noop.lua index ad93ad7f5..b51bf15a5 100644 --- a/yazi-plugin/preset/plugins/noop.lua +++ b/yazi-plugin/preset/plugins/noop.lua @@ -4,6 +4,7 @@ function M:peek() end function M:seek() end +---@return yazi.PreloaderReturnValue function M:preload() return 1 end return M diff --git a/yazi-plugin/preset/plugins/pdf.lua b/yazi-plugin/preset/plugins/pdf.lua index 4854ba743..b409a7170 100644 --- a/yazi-plugin/preset/plugins/pdf.lua +++ b/yazi-plugin/preset/plugins/pdf.lua @@ -1,5 +1,6 @@ local M = {} +---@return nil function M:peek() local cache = ya.file_cache(self) if not cache then @@ -12,6 +13,7 @@ function M:peek() end end +---@return nil function M:seek(units) local h = cx.active.current.hovered if h and h.url == self.file.url then @@ -20,6 +22,7 @@ function M:seek(units) end end +---@return yazi.PreloaderReturnValue function M:preload() local cache = ya.file_cache(self) if not cache or fs.cha(cache) then diff --git a/yazi-plugin/preset/plugins/session.lua b/yazi-plugin/preset/plugins/session.lua index 6a5fcfdfc..6b5629a92 100644 --- a/yazi-plugin/preset/plugins/session.lua +++ b/yazi-plugin/preset/plugins/session.lua @@ -1,3 +1,4 @@ +---@return nil local function setup(_, opts) if opts.sync_yanked then ps.sub_remote("yank", function(body) ya.manager_emit("update_yanked", { cut = body.cut, urls = body }) end) diff --git a/yazi-plugin/preset/plugins/video.lua b/yazi-plugin/preset/plugins/video.lua index e8b9fe525..9de37144c 100644 --- a/yazi-plugin/preset/plugins/video.lua +++ b/yazi-plugin/preset/plugins/video.lua @@ -1,5 +1,6 @@ local M = {} +---@return nil function M:peek() local cache = ya.file_cache(self) if not cache then @@ -12,6 +13,7 @@ function M:peek() end end +---@return nil function M:seek(units) local h = cx.active.current.hovered if h and h.url == self.file.url then @@ -22,6 +24,7 @@ function M:seek(units) end end +---@return yazi.PreloaderReturnValue function M:preload() local percentage = 5 + self.skip if percentage > 95 then diff --git a/yazi-plugin/preset/plugins/zoxide.lua b/yazi-plugin/preset/plugins/zoxide.lua index 2a57d87b8..969d04eff 100644 --- a/yazi-plugin/preset/plugins/zoxide.lua +++ b/yazi-plugin/preset/plugins/zoxide.lua @@ -11,6 +11,8 @@ local function fail(s, ...) ya.notify { title = "Zoxide", content = string.format(s, ...), timeout = 5, level = "error" } end +---@param cwd string +---@return integer local function head(cwd) local child = Command("zoxide"):args({ "query", "-l" }):stdout(Command.PIPED):spawn() if not child then @@ -31,6 +33,10 @@ local function head(cwd) return n end +---@class yazi.ZoxideOpts +---@field update_db? boolean + +---@param opts yazi.ZoxideOpts local function setup(_, opts) opts = opts or {} @@ -48,6 +54,7 @@ local function setup(_, opts) end end +---@return nil local function entry() local st = state() if st.empty == true then diff --git a/yazi-plugin/preset/types.lua b/yazi-plugin/preset/types.lua new file mode 100644 index 000000000..3ae051dcf --- /dev/null +++ b/yazi-plugin/preset/types.lua @@ -0,0 +1,13 @@ +---@meta + +-- This file contains some of the types used in yazi. It only exists to +-- provide these types and should not be loaded at runtime. +return + +---@alias yazi.FolderType "PARENT" | "CURRENT" | "PREVIEW" + +---@alias yazi.PreloaderReturnValue +---| 0 # Failure, don't continue +---| 1 # Success, don't continue +---| 2 # Failure, continue +---| 3 # Success, continue diff --git a/yazi-plugin/preset/ya.lua b/yazi-plugin/preset/ya.lua index 8713c0a15..3871c92ec 100644 --- a/yazi-plugin/preset/ya.lua +++ b/yazi-plugin/preset/ya.lua @@ -1,7 +1,13 @@ table.unpack = table.unpack or unpack +---@class yazi.Ya ya = ya or {} +---@param min number +---@param x number +---@param max number +---@return number +---@nodiscard function ya.clamp(min, x, max) if x < min then return min @@ -12,8 +18,16 @@ function ya.clamp(min, x, max) end end -function ya.round(x) return x >= 0 and math.floor(x + 0.5) or math.ceil(x - 0.5) end +---@param x number +---@return number +---@nodiscard +function ya.round(x) + return x >= 0 and math.floor(x + 0.5) or math.ceil(x - 0.5) +end +---@param t table +---@return table +---@nodiscard function ya.flat(t) local r = {} for _, v in ipairs(t) do @@ -28,8 +42,17 @@ function ya.flat(t) return r end -function ya.basename(str) return string.gsub(str, "(.*[/\\])(.*)", "%2") end +---@param str string +---@return string +---@nodiscard +function ya.basename(str) +---@diagnostic disable-next-line: redundant-return-value + return string.gsub(str, "(.*[/\\])(.*)", "%2") +end +---@param size number +---@return string +---@nodiscard function ya.readable_size(size) local units = { "B", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q" } local i = 1 @@ -40,6 +63,8 @@ function ya.readable_size(size) return string.format("%.1f%s", size, units[i]) end +---@param path string +---@return string function ya.readable_path(path) local home = os.getenv("HOME") or os.getenv("USERPROFILE") if not home then