From 7b20ac1fbf25ec399a89a63d84fd7b7b4a037bee Mon Sep 17 00:00:00 2001 From: phanium <91544758+phanen@users.noreply.github.com> Date: Sat, 5 Jul 2025 15:59:11 +0800 Subject: [PATCH 1/3] chore: fix luals types --- .luarc.jsonc | 32 ++++++++++++++ lua/dial/augend/case.lua | 44 ++++++++++---------- lua/dial/augend/common.lua | 5 ++- lua/dial/augend/constant.lua | 19 +++++---- lua/dial/augend/date.lua | 62 ++++++++++++++++------------ lua/dial/augend/decimal_fraction.lua | 15 ++----- lua/dial/augend/hexcolor.lua | 11 +++-- lua/dial/augend/integer.lua | 28 ++++++------- lua/dial/augend/misc.lua | 8 ++-- lua/dial/augend/paren.lua | 7 ++-- lua/dial/augend/semver.lua | 9 ++-- lua/dial/augend/user.lua | 10 ++--- lua/dial/command.lua | 15 ++++--- lua/dial/config.lua | 2 + lua/dial/handle.lua | 8 ++-- lua/dial/map.lua | 5 ++- lua/dial/types.lua | 8 ++-- lua/dial/util.lua | 22 ++++++++-- run | 18 +++++--- tests/dial/augend/hexcolor_spec.lua | 2 + tests/minimal_init.lua | 10 ++--- 21 files changed, 200 insertions(+), 140 deletions(-) create mode 100644 .luarc.jsonc diff --git a/.luarc.jsonc b/.luarc.jsonc new file mode 100644 index 0000000..0725ef8 --- /dev/null +++ b/.luarc.jsonc @@ -0,0 +1,32 @@ +{ + "$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json", + "runtime": { "version": "LuaJIT" }, + "workspace": { + "library": [ + "$VIMRUNTIME", + "${3rd}/busted/library", + "${3rd}/luassert/library", + "./lua" + ] + }, + "diagnostics": { + "libraryFiles": "Disable", + "groupFileStatus": { + "strict": "Opened", + "strong": "Opened", + "ambiguity": "Opened", + "duplicate": "Opened", + "global": "Opened", + "luadoc": "Opened", + "redefined": "Opened", + "type-check": "Opened", + "unbalanced": "Opened", + "unused": "Opened" + }, + "groupSeverity": { + "strong": "Warning", + "strict": "Warning" + }, + "unusedLocalExclude": ["_*"] + } +} diff --git a/lua/dial/augend/case.lua b/lua/dial/augend/case.lua index 47b3462..9c66705 100644 --- a/lua/dial/augend/case.lua +++ b/lua/dial/augend/case.lua @@ -4,12 +4,11 @@ local util = require "dial.util" local M = {} ---@alias casetype '"PascalCase"' | '"camelCase"' | '"snake_case"' | '"kebab-case"' | '"SCREAMING_SNAKE_CASE"' ----@alias extractf fun(word: string) -> string[] | nil ----@alias constractf fun(terms: string[]) -> string +---@alias extractf fun(word: string): string[]|nil +---@alias constractf fun(terms: string[]): string ---@alias casepattern { word_regex: string, extract: extractf, constract: constractf } ----@class AugendCase ----@implement Augend +---@class AugendCase: Augend ---@field config { types: casetype[], cyclic: boolean } ---@field patterns casepattern[] local AugendCase = {} @@ -39,9 +38,7 @@ M.case_patterns["camelCase"] = { end end table.insert(subwords, word:sub(ptr, word:len())) - return vim.tbl_map(function(s) - return s:lower() - end, subwords) + return vim.tbl_map(string.lower, subwords) end, ---@param terms string[] @@ -78,9 +75,7 @@ M.case_patterns["PascalCase"] = { end end table.insert(subwords, word:sub(ptr, word:len())) - return vim.tbl_map(function(s) - return s:lower() - end, subwords) + return vim.tbl_map(string.lower, subwords) end, ---@param terms string[] @@ -163,9 +158,7 @@ M.case_patterns["SCREAMING_SNAKE_CASE"] = { end end table.insert(subwords, word:sub(ptr, word:len())) - return vim.tbl_map(function(s) - return s:lower() - end, subwords) + return vim.tbl_map(string.lower, subwords) end, ---@param terms string[] @@ -176,7 +169,7 @@ M.case_patterns["SCREAMING_SNAKE_CASE"] = { } ---@param config { types: casetype[], cyclic?: boolean } ----@return Augend +---@return AugendCase function M.new(config) vim.validate("cyclic", config.cyclic, "boolean", true) @@ -195,9 +188,14 @@ function M.new(config) end return false end) - local patterns = vim.tbl_map(function(type) - return M.case_patterns[type] - end, config.types) + + local patterns = vim.tbl_map( + ---@overload fun(type: casetype): casepattern + function(type) + return M.case_patterns[type] + end, + config.types + ) -- local query = prefix .. util.if_expr(natural, "", "-?") .. "[" .. radix_to_query_character(radix) .. delimiter .. "]+" return setmetatable({ @@ -214,7 +212,7 @@ function AugendCase:find(line, cursor) local most_front_range = nil for _, caseptn in ipairs(self.patterns) do - ---@type textrange + ---@type textrange? local range = common.find_pattern_regex(caseptn.word_regex)(line, cursor) if range ~= nil then if most_front_range == nil or range.from < most_front_range.from then @@ -227,9 +225,9 @@ end ---@param text string ---@param addend integer ----@param cursor? integer ----@return { text?: string, cursor?: integer } -function AugendCase:add(text, addend, cursor) +---@param _cursor? integer +---@return addresult +function AugendCase:add(text, addend, _cursor) local len_patterns = #self.patterns ---@type integer local index @@ -243,7 +241,7 @@ function AugendCase:add(text, addend, cursor) local terms = self.patterns[index].extract(text) - local new_index + local new_index ---@type integer if self.config.cyclic then new_index = (len_patterns + (index - 1 + addend) % len_patterns) % len_patterns + 1 else @@ -258,7 +256,7 @@ function AugendCase:add(text, addend, cursor) if new_index == index then return { cursor = text:len() } end - text = self.patterns[new_index].constract(terms) + text = self.patterns[new_index].constract(assert(terms)) return { text = text, cursor = text:len() } end diff --git a/lua/dial/augend/common.lua b/lua/dial/augend/common.lua index 37d5fd8..a4ab52d 100644 --- a/lua/dial/augend/common.lua +++ b/lua/dial/augend/common.lua @@ -1,7 +1,5 @@ -- augend で共通して用いられる関数。 -local util = require "dial.util" - local M = {} ---augend の find field を簡単に実装する。 @@ -55,7 +53,9 @@ function M.find_pattern_regex(ptn, allow_match_before_cursor) local s, e = vim.regex(ptn):match_str(line:sub(idx_start)) if s then + ---@type integer s = s + idx_start -- 上で得られた s は相対位置なので + ---@type integer e = e + idx_start - 1 -- 上で得られた s は相対位置なので -- 検索結果があったら @@ -81,6 +81,7 @@ function M.find_pattern_regex(ptn, allow_match_before_cursor) end ---@param elems string[] +---@return string function M.enum_to_regex(elems) return table.concat(elems, [[\|]]) end diff --git a/lua/dial/augend/constant.lua b/lua/dial/augend/constant.lua index b84220c..37c548d 100644 --- a/lua/dial/augend/constant.lua +++ b/lua/dial/augend/constant.lua @@ -3,8 +3,7 @@ local common = require "dial.augend.common" ---@alias AugendConstantConfig { elements: string[], cyclic: boolean, pattern_regexp: string, preserve_case: boolean, match_before_cursor: boolean } ----@class AugendConstant ----@implement Augend +---@class AugendConstant: Augend ---@field config AugendConstantConfig local AugendConstant = {} @@ -34,7 +33,7 @@ local function preserve_case(word) end ---@param config { elements: string[], word?: boolean, cyclic?: boolean, pattern_regexp?: string, preserve_case?: boolean, match_before_cursor?: boolean } ----@return Augend +---@return AugendConstant function M.new(config) util.validate_list("config.elements", config.elements, "string") @@ -69,9 +68,14 @@ end ---@param cursor? integer ---@return textrange? function AugendConstant:find(line, cursor) - local escaped_elements = vim.tbl_map(function(e) - return vim.fn.escape(e, [[/\]]) - end, self.config.elements) + local escaped_elements = vim.tbl_map( + ---@param e string + ---@return string + function(e) + return vim.fn.escape(e, [[/\]]) + end, + self.config.elements + ) local vim_regex_ptn = self.config.pattern_regexp:format(table.concat(escaped_elements, [[\|]])) return common.find_pattern_regex(vim_regex_ptn, self.config.match_before_cursor)(line, cursor) end @@ -79,12 +83,13 @@ end ---@param text string ---@param addend integer ---@param cursor? integer ----@return { text?: string, cursor?: integer } +---@return addresult function AugendConstant:add(text, addend, cursor) local elements = self.config.elements local n_patterns = #elements local n = 1 + ---@type fun(elem: string): boolean local query if self.config.preserve_case then query = function(elem) diff --git a/lua/dial/augend/date.lua b/lua/dial/augend/date.lua index b0a8eab..cf5c795 100644 --- a/lua/dial/augend/date.lua +++ b/lua/dial/augend/date.lua @@ -3,14 +3,24 @@ local common = require "dial.augend.common" local M = {} +---@class dial.osdate:osdate +---@field year integer +---@field month integer +---@field day integer +---@field hour integer +---@field min integer +---@field sec integer +---@field wday integer +---@field yday integer + ---@alias datekind '"year"' | '"month"' | '"day"' | '"hour"' | '"min"' | '"sec"' ---@alias dttable table ----@alias dateparser fun(string, osdate): osdate ----@alias dateformatter fun(osdate): string +---@alias dateparser fun(text: string, date: dial.osdate): dial.osdate +---@alias dateformatter fun(date: integer): string ---@alias dateelement {kind?: datekind, regex: string, update_date: dateparser, format?: dateformatter} ---@param datekind datekind | nil ----@return fun(string, osdate): osdate +---@return dateparser local function simple_updater(datekind) if datekind == nil then return function(_, date) @@ -18,6 +28,7 @@ local function simple_updater(datekind) end end return function(text, date) + ---@type integer date[datekind] = tonumber(text) return date end @@ -113,7 +124,7 @@ local date_elements = { kind = "hour", regex = [[\d\d]], update_date = function(text, date) - local hour = tonumber(text) + local hour = assert(tonumber(text)) if date.hour < 12 and hour >= 12 then date.hour = hour - 12 elseif date.hour >= 12 and hour < 12 then @@ -179,7 +190,7 @@ local date_elements = { kind = "hour", regex = [[\d\{1,2\}]], update_date = function(text, date) - local hour = tonumber(text) + local hour = assert(tonumber(text)) if date.hour < 12 and hour >= 12 then date.hour = hour - 12 elseif date.hour >= 12 and hour < 12 then @@ -440,7 +451,7 @@ end ---@param line string ---@param cursor? integer ----@return {range: textrange, dt_info: osdate, kind: datekind}? +---@return {range: textrange, dt_info: dial.osdate, kind: datekind}? function DateFormat:find(line, cursor) local range = common.find_pattern_regex(self:regex())(line, cursor) if range == nil then @@ -452,13 +463,14 @@ function DateFormat:find(line, cursor) cursor = 0 end + ---@type string[] local matchlist = vim.fn.matchlist(line:sub(range.from, range.to), self:regex()) local scan_cursor = range.from - 1 local flag_set_status = scan_cursor >= cursor - local dt_info = os.date("*t", 0) --[[@as osdate]] + local dt_info = os.date("*t", 0) --[[@as dial.osdate]] do - local now = os.date("*t", os.time()) --[[@as osdate]] + local now = os.date("*t", os.time()) --[[@as dial.osdate]] dt_info.month = now.month dt_info.year = now.year dt_info.isdst = now.isdst @@ -488,7 +500,7 @@ end ---@param line string ---@param cursor? integer ----@return {range: textrange, dt_info: osdate, kind: datekind}? +---@return {range: textrange, dt_info: dial.osdate, kind: datekind}? function DateFormat:find_with_validity_check(line, cursor) local find_result = self:find(line, cursor) if find_result == nil then @@ -510,7 +522,7 @@ end ---@return addresult function DateFormat:strftime(time, datekind) local text = "" - local cursor + local cursor ---@type integer? for _, pattern in ipairs(self.sequences) do if pattern ~= "%" and vim.startswith(pattern, "%") then local date_element = self:get_date_elements(pattern) @@ -533,15 +545,14 @@ function DateFormat:strftime(time, datekind) end end ----@class AugendDate ----@implement Augend +---@class AugendDate: Augend ---@field kind datekind ---@field config {pattern: string, default_kind: datekind, only_valid: boolean, word: boolean, clamp: boolean, end_sensitive: boolean, custom_date_elements: dateelement} ---@field date_format DateFormat local AugendDate = {} ---@param config {pattern: string, default_kind: datekind, only_valid?: boolean, word?: boolean, clamp?: boolean, end_sensitive?: boolean, custom_date_elements?: table} ----@return Augend +---@return AugendDate function M.new(config) vim.validate("pattern", config.pattern, "string") vim.validate("default_kind", config.default_kind, "string") @@ -568,7 +579,7 @@ end ---@param cursor? integer ---@return textrange? function AugendDate:find(line, cursor) - local find_result + local find_result ---@type {range: textrange, dt_info: dial.osdate, kind: datekind}? if self.config.only_valid then find_result = self.date_format:find_with_validity_check(line, cursor) else @@ -584,12 +595,8 @@ end ---@param cursor? integer ---@return textrange? function AugendDate:find_stateful(line, cursor) - local find_result - if self.config.only_valid then - find_result = self.date_format:find_with_validity_check(line, cursor) - else - find_result = self.date_format:find(line, cursor) - end + local find_result = self.config.only_valid and self.date_format:find_with_validity_check(line, cursor) + or self.date_format:find(line, cursor) if find_result == nil then return nil end @@ -614,14 +621,15 @@ local function calc_end_day(year, month) end end ----@param dt_info osdate +---@param dt_info dial.osdate ---@param kind datekind ---@param addend integer ---@param clamp boolean ---@param end_sensitive boolean ----@return osdate +---@return dial.osdate local function update_dt_info(dt_info, kind, addend, clamp, end_sensitive) if kind ~= "year" and kind ~= "month" then + ---@type integer dt_info[kind] = dt_info[kind] + addend return dt_info end @@ -629,9 +637,10 @@ local function update_dt_info(dt_info, kind, addend, clamp, end_sensitive) local end_day_before_add = calc_end_day(dt_info.year, dt_info.month) local day_before_add = dt_info.day dt_info.day = 1 + ---@type integer dt_info[kind] = dt_info[kind] + addend -- update date information to existent one - dt_info = os.date("*t", os.time(dt_info)) --[[@as osdate]] + dt_info = os.date("*t", os.time(dt_info)) --[[@as dial.osdate]] local end_day_after_add = calc_end_day(dt_info.year, dt_info.month) if end_sensitive and end_day_before_add == day_before_add then @@ -646,9 +655,9 @@ end ---@param text string ---@param addend integer ----@param cursor? integer ----@return { text?: string, cursor?: integer } -function AugendDate:add(text, addend, cursor) +---@param _cursor? integer +---@return addresult +function AugendDate:add(text, addend, _cursor) local find_result = self.date_format:find(text) if find_result == nil or self.kind == nil then return {} @@ -662,6 +671,7 @@ function AugendDate:add(text, addend, cursor) return self.date_format:strftime(time, self.kind) end +---@type table M.alias = {} M.alias["%Y/%m/%d"] = M.new { diff --git a/lua/dial/augend/decimal_fraction.lua b/lua/dial/augend/decimal_fraction.lua index 87d92ec..d869e8c 100644 --- a/lua/dial/augend/decimal_fraction.lua +++ b/lua/dial/augend/decimal_fraction.lua @@ -1,8 +1,6 @@ -local common = require "dial.augend.common" local util = require "dial.util" ----@class AugendDecimalFraction ----@implement Augend +---@class AugendDecimalFraction: Augend ---@field signed boolean ---@field point_char string local AugendDecimalFraction = {} @@ -10,7 +8,7 @@ local AugendDecimalFraction = {} local M = {} ---@param config { signed?: boolean, point_char?: string } ----@return Augend +---@return AugendDecimalFraction function M.new(config) vim.validate("signed", config.signed, "boolean", true) vim.validate("point_char", config.point_char, "string", true) @@ -31,12 +29,7 @@ end ---@return textrange? function AugendDecimalFraction:find(line, cursor) local idx = 1 - local integer_pattern - if self.signed then - integer_pattern = "%-?%d+" - else - integer_pattern = "%d+" - end + local integer_pattern = self.signed and "%-?%d+" or "%d+" while idx <= #line do local idx_integer_start, idx_integer_end = line:find(integer_pattern, idx) if idx_integer_start == nil then @@ -98,7 +91,7 @@ end ---@param text string ---@param addend integer ---@param cursor? integer ----@return { text?: string, cursor?: integer } +---@return addresult function AugendDecimalFraction:add(text, addend, cursor) local point_pos = text:find(self.point_char, 1, true) diff --git a/lua/dial/augend/hexcolor.lua b/lua/dial/augend/hexcolor.lua index 2132261..cab4e37 100644 --- a/lua/dial/augend/hexcolor.lua +++ b/lua/dial/augend/hexcolor.lua @@ -13,8 +13,7 @@ end ---@alias colorcase '"upper"' | '"lower"' | '"prefer_upper"' | '"prefer_lower"' ---@alias colorkind '"r"' | '"g"' | '"b"' | '"all"' ----@class AugendHexColor ----@implement Augend +---@class AugendHexColor: Augend ---@field config { case: colorcase } ---@field kind colorkind local AugendHexColor = {} @@ -22,7 +21,7 @@ local AugendHexColor = {} local M = {} ---@param config? { case: colorcase } ----@return Augend +---@return AugendHexColor function M.new(config) config = config or { case = "prefer_lower" } @@ -38,7 +37,7 @@ function M.new(config) return setmetatable({ config = config, kind = "all", - }, { __index = AugendHexColor }) --[[@as Augend]] + }, { __index = AugendHexColor }) end ---@param line string @@ -72,7 +71,7 @@ end ---@param text string ---@param addend integer ---@param cursor? integer ----@return { text?: string, cursor?: integer } +---@return addresult function AugendHexColor:add(text, addend, cursor) local r = tonumber(text:sub(2, 3), 16) local g = tonumber(text:sub(4, 5), 16) @@ -107,7 +106,7 @@ function AugendHexColor:add(text, addend, cursor) text = "#" .. string.format("%02x", r) .. string.format("%02x", g) .. string.format("%02x", b) if self.config.case == "upper" then - text = text:upper() + text = text:upper() ---@type string elseif self.config.case == "lower" then text = text:lower() elseif self.config.case == "prefer_upper" then diff --git a/lua/dial/augend/integer.lua b/lua/dial/augend/integer.lua index dc63c0d..fa56f1e 100644 --- a/lua/dial/augend/integer.lua +++ b/lua/dial/augend/integer.lua @@ -3,8 +3,7 @@ local util = require "dial.util" ---@alias AugendIntegerConfig {} ----@class AugendInteger ----@implement Augend +---@class AugendInteger: Augend ---@field radix integer ---@field prefix string ---@field natural boolean @@ -18,7 +17,7 @@ local M = {} ---@class BigInt ---@field sign 1|-1 ----@field digits table +---@field digits integer[] ---@field radix integer ---@field plus fun(self:BigInt, value:BigInt, natural:boolean):BigInt `value` must be positive ---@field minus fun(self:BigInt, value:BigInt, natural:boolean):BigInt `value` must be positive @@ -38,6 +37,7 @@ function BigInt.new(n, radix) local base_len = 8 local base = self.radix ^ base_len + ---@param digits integer[] local remove_top_0 = function(digits) for i = #digits, 2, -1 do if digits[i] == 0 then @@ -85,10 +85,10 @@ function BigInt.new(n, radix) -- For now, self and value is positive -- Calculate self + value - local max_digits + local max_digits ---@type integer if #self.digits < #value.digits then max_digits = #value.digits - self, value = value, self + self, value = value, self ---@type BigInt, BigInt else max_digits = #self.digits end @@ -135,10 +135,10 @@ function BigInt.new(n, radix) return self end - local max_digits + local max_digits ---@type integer if value_is_large then max_digits = #value.digits - self, value = value, self + self, value = value, self ---@type BigInt, BigInt self.sign = -1 else max_digits = #self.digits @@ -166,12 +166,8 @@ function BigInt.new(n, radix) ---@param case '"upper"' | '"lower"' ---@return string function self:to_string(case) - local digits - if case == "upper" then - digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - else - digits = "0123456789abcdefghijklmnopqrstuvwxyz" - end + local digits = case == "upper" and "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + or "0123456789abcdefghijklmnopqrstuvwxyz" local ret = "" if self.sign == -1 then @@ -239,7 +235,7 @@ local function radix_to_query_character(radix) end ---@param config { radix?: integer, prefix?: string, natural?: boolean, case?: '"upper"' | '"lower"', delimiter?: string, delimiter_digits?: number } ----@return Augend +---@return AugendInteger function M.new(config) vim.validate("radix", config.radix, "number", true) vim.validate("prefix", config.prefix, "string", true) @@ -285,7 +281,7 @@ end ---@param text string ---@param addend integer ---@param cursor? integer ----@return { text?: string, cursor?: integer } +---@return addresult function AugendInteger:add(text, addend, cursor) local n_prefix = #self.prefix local subtext = text:sub(n_prefix + 1) @@ -306,7 +302,7 @@ function AugendInteger:add(text, addend, cursor) n = n:minus(BigInt.new(-addend, self.radix), self.natural) end - local digits + local digits ---@type string if n_string_digit == n_actual_digit then -- 増減前の数字が0か0始まりでない数字だったら -- text = ("%d"):format(n) diff --git a/lua/dial/augend/misc.lua b/lua/dial/augend/misc.lua index 253944d..6d2b72d 100644 --- a/lua/dial/augend/misc.lua +++ b/lua/dial/augend/misc.lua @@ -1,5 +1,3 @@ -local util = require "dial.util" -local common = require "dial.augend.common" local user = require "dial.augend.user" local M = {} @@ -8,9 +6,9 @@ M.alias = {} M.alias.markdown_header = user.new { ---@param line string - ---@param cursor? integer + ---@param _cursor? integer ---@return textrange? - find = function(line, cursor) + find = function(line, _cursor) local header_mark_s, header_mark_e = line:find "^#+" if header_mark_s == nil or header_mark_e >= 7 then return nil @@ -21,7 +19,7 @@ M.alias.markdown_header = user.new { ---@param text string ---@param addend integer ---@param cursor? integer - ---@return { text?: string, cursor?: integer } + ---@return addresult add = function(text, addend, cursor) local n = #text n = n + addend diff --git a/lua/dial/augend/paren.lua b/lua/dial/augend/paren.lua index 1c7da05..e351733 100644 --- a/lua/dial/augend/paren.lua +++ b/lua/dial/augend/paren.lua @@ -1,8 +1,6 @@ local util = require "dial.util" -local common = require "dial.augend.common" ----@class AugendParen ----@implement Augend +---@class AugendParen: Augend ---@field config { patterns: string[][], escape_char?: string, cyclic: boolean, nested: boolean } ---@field find_pattern string local AugendParen = {} @@ -50,6 +48,7 @@ local function find_nested_paren(line, open, close, nested, cursor_idx, escape_c -- idx を増やしつつ走査。 -- 括弧の open, close または escape char に当たったら特別処理を入れる。 -- open と close が同じパターン列の場合は close を優先。 + ---@type integer?, integer? local from, to = (function() -- escape 文字: escaped のトグルを行う if escape_char ~= nil and precedes(line, escape_char, idx) then @@ -171,7 +170,7 @@ end ---@param text string ---@param addend integer ---@param cursor? integer ----@return { text?: string, cursor?: integer } +---@return addresult function AugendParen:add(text, addend, cursor) local n_patterns = #self.config.patterns local n = 1 diff --git a/lua/dial/augend/semver.lua b/lua/dial/augend/semver.lua index 19b3faf..fe3ceb6 100644 --- a/lua/dial/augend/semver.lua +++ b/lua/dial/augend/semver.lua @@ -1,6 +1,6 @@ -local util = require "dial.util" local common = require "dial.augend.common" +---@diagnostic disable-next-line: unused-local, unused-function local function cast_u8(n) if n <= 0 then return 0 @@ -11,15 +11,14 @@ local function cast_u8(n) return n end ----@class AugendSemver ----@implement Augend +---@class AugendSemver: Augend ---@field kind '"major"' | '"minor"' | '"patch"' local AugendSemver = {} local M = {} ---@param config {} ----@return Augend +---@return AugendSemver function M.new(config) vim.validate("kind", config.kind, "string", true) @@ -68,7 +67,7 @@ end ---@param text string ---@param addend integer ---@param cursor? integer ----@return { text?: string, cursor?: integer } +---@return addresult function AugendSemver:add(text, addend, cursor) local iterator = text:gmatch "%d+" local major = tonumber(iterator()) diff --git a/lua/dial/augend/user.lua b/lua/dial/augend/user.lua index 1a60c8c..46927ff 100644 --- a/lua/dial/augend/user.lua +++ b/lua/dial/augend/user.lua @@ -1,15 +1,11 @@ -local util = require "dial.util" -local common = require "dial.augend.common" - ---@alias AugendUserConfig { find: findf, add: addf } ----@class AugendUser ----@implement Augend +---@class AugendUser: Augend ---@field config AugendUserConfig local AugendUser = {} ---@param config AugendUserConfig ----@return Augend +---@return AugendUser function AugendUser.new(config) vim.validate("find", config.find, "function") vim.validate("add", config.add, "function") @@ -27,7 +23,7 @@ end ---@param text string ---@param addend integer ---@param cursor? integer ----@return { text?: string, cursor?: integer } +---@return addresult? function AugendUser:add(text, addend, cursor) return self.config.add(text, addend, cursor) end diff --git a/lua/dial/command.lua b/lua/dial/command.lua index 17f1a2f..a23c641 100644 --- a/lua/dial/command.lua +++ b/lua/dial/command.lua @@ -12,7 +12,7 @@ VISUAL_BLOCK = string.char(22) ---Select the most appropriate augend from given augend group (in NORMAL mode). ---@param group_name? string function M.select_augend_normal(group_name) - local augends + local augends ---@type Augend[] if group_name ~= nil then augends = config.augends.group[group_name] elseif vim.v.register == "=" then @@ -41,7 +41,7 @@ end ---Select the most appropriate augend from given augend group (in VISUAL mode). ---@param group_name? string function M.select_augend_visual(group_name) - local augends + local augends ---@type Augend[] if group_name ~= nil then augends = config.augends.group[group_name] elseif vim.v.register == "=" then @@ -79,7 +79,7 @@ function M.select_augend_visual(group_name) local line_min = math.min(line1, line2) local line_max = math.max(line1, line2) local col_min = math.min(col1, col2) - local col_max = math.max(col1, col2) + local _col_max = math.max(col1, col2) local lines = {} for line_num = line_min, line_max, 1 do local line = vim.fn.getline(line_num) @@ -95,7 +95,7 @@ function M.select_augend_visual(group_name) local text = vim.fn.getline(line_min) if line1 == line2 then local col_max = math.max(col1, col2) - text = text:sub(col_min, col_max) + text = text:sub(col_min, col_max) ---@type string else text = text:sub(col_min) end @@ -138,13 +138,13 @@ end ---@param direction direction ---@param stairlike boolean function M.operator_visual(direction, stairlike) - local mode = vim.fn.visualmode(0) + local mode = vim.fn.visualmode() local _, line1, col1, _ = unpack(vim.fn.getpos "'[") local _, line2, col2, _ = unpack(vim.fn.getpos "']") local tier = 1 ---@param lnum integer - ---@param range {from: integer, to?: integer} + ---@param range {from: integer, to: integer?} local function operate_line(lnum, range) local line = vim.fn.getline(lnum) local result = handler:operate_visual(line, range, direction, tier) @@ -199,6 +199,9 @@ function M.textobj() handler:find_text_range(line, col) end +---@param direction direction +---@param line_range {from: integer, to: integer?} +---@param groups string[] function M.command(direction, line_range, groups) local group_name = groups[1] if group_name == nil and vim.v.register == "=" then diff --git a/lua/dial/config.lua b/lua/dial/config.lua index 18b1170..36b1769 100644 --- a/lua/dial/config.lua +++ b/lua/dial/config.lua @@ -4,6 +4,7 @@ local M = {} ---@class augends ---@field group table +---@field filetype table M.augends = { group = { default = { @@ -73,6 +74,7 @@ end ---グループを取得する。 ---@param group_name string +---@return Augend[] function M.augends:get(group_name) return self.group[group_name] end diff --git a/lua/dial/handle.lua b/lua/dial/handle.lua index 96b4ebb..5807cbe 100644 --- a/lua/dial/handle.lua +++ b/lua/dial/handle.lua @@ -47,7 +47,7 @@ end ---@param cursor? integer ---@return {cursor_loc: integer, start_pos: integer, neg_end_pos: integer} local function calc_score(s, e, cursor) - local cursor_loc + local cursor_loc ---@type integer if (cursor or 0) > e then cursor_loc = 2 elseif (cursor or 0) < s then @@ -71,6 +71,7 @@ end ---Compare the score. ---If and only if `self` has the higher priority than `rhs`, returns true. ---@param rhs Score +---@return boolean function Score.cmp(self, rhs) if self.cursor_loc < rhs.cursor_loc then return true @@ -220,10 +221,11 @@ function Handler:operate(line, cursor, direction, additive) end ---The process that runs when operator is called (in VISUAL mode). ----@param selected_range {from: integer, to?: integer} +---@param line string +---@param selected_range {from: integer, to: integer?} ---@param direction direction ---@param tier integer ----@return {range?: textrange, text?: string} +---@return {range: textrange, text?: string} function Handler:operate_visual(line, selected_range, direction, tier) if self.active_augend == nil then return {} diff --git a/lua/dial/map.lua b/lua/dial/map.lua index 31619ad..d9a71a3 100644 --- a/lua/dial/map.lua +++ b/lua/dial/map.lua @@ -1,10 +1,10 @@ local M = {} -local command = require "dial.command" local util = require "dial.util" ---Sandwich input string between and . ---@param body string +---@return string local function cmdcr(body) local cmd_sequences = "" local cr_sequences = "" @@ -16,8 +16,9 @@ end ---@param mode mode ---@param group_name? string ---@param count? integer +---@return string local function _cmd_sequence(direction, mode, group_name, count) - local select + local select ---@type string if group_name == nil then select = cmdcr([[lua require"dial.command".select_augend_]] .. mode .. "()") else diff --git a/lua/dial/types.lua b/lua/dial/types.lua index b0c3cc8..2128969 100644 --- a/lua/dial/types.lua +++ b/lua/dial/types.lua @@ -6,11 +6,11 @@ ---@alias textrange {from: integer, to: integer} ---@alias addresult {text?: string, cursor?: integer} ----@alias findf fun(line: string, cursor?: integer) -> textrange? ----@alias addf fun(text: string, addend: integer, cursor?: integer) -> addresult? +---@alias findf fun(line: string, cursor?: integer): textrange? +---@alias addf fun(text: string, addend: integer, cursor?: integer): addresult? ----@alias findmethod fun(self: Augend, line: string, cursor?: integer) -> textrange? ----@alias addmethod fun(self: Augend, text: string, addend: integer, cursor?: integer) -> addresult? +---@alias findmethod fun(self: Augend, line: string, cursor?: integer): textrange? +---@alias addmethod fun(self: Augend, text: string, addend: integer, cursor?: integer): addresult ---@class Augend ---@field find findmethod diff --git a/lua/dial/util.lua b/lua/dial/util.lua index 0acd16d..3161338 100644 --- a/lua/dial/util.lua +++ b/lua/dial/util.lua @@ -2,7 +2,8 @@ local M = {} -- NOTE: Needed until compatibility with Neovim 0.9 is dropped -local islist = vim.fn.has('nvim-0.10') == 1 and vim.islist or vim.tbl_islist +---@diagnostic disable-next-line: deprecated +local islist = vim.fn.has "nvim-0.10" == 1 and vim.islist or vim.tbl_islist ---@generic T ---@param cond boolean @@ -27,8 +28,14 @@ function M.unwrap_or(x, default) return x end +---@generic T +---@param list T[] +---@return { [T]: boolean } function M.Set(list) + ---@generic T + ---@type T[] local set = {} + ---@diagnostic disable-next-line: no-unknown for _, l in ipairs(list) do set[l] = true end @@ -38,7 +45,7 @@ end -- Check if the argument is a valid list (which does not contain nil). ---@param name string ---@param list any[] ----@param arg1 string | function +---@param arg1 string | fun(v:any):boolean, string? ---@param arg2? string function M.validate_list(name, list, arg1, arg2) if not islist(list) then @@ -79,7 +86,8 @@ end ---Returns the indices with the value nil. ---returns an index array ----@param tbl array +---@generic T +---@param tbl T[] ---@return integer[] function M.index_with_nil_value(tbl) -- local maxn, k = 0, nil @@ -131,6 +139,11 @@ function M.filter_map_zip(fn, ary) return a end +---@param n integer +---@param b integer? +---@param wid integer? +---@param pad string? +---@return string function M.tostring_with_base(n, b, wid, pad) n = math.floor(n) if not b or b == 10 then @@ -162,6 +175,9 @@ end -- util.try_get_keys({foo = "bar", hoge = "fuga", teka = "pika"}, ["teka", "foo"]) -- -> ["pika", "bar"] +---@param tbl string[] +---@param keylst string[] +---@return string[] | nil, string? function M.try_get_keys(tbl, keylst) if not islist(keylst) then return nil, "the 2nd argument is not list." diff --git a/run b/run index ade1612..9aef23e 100755 --- a/run +++ b/run @@ -2,6 +2,7 @@ TESTS_INIT=tests/minimal_init.lua TESTS_DIR=tests +VIMRUNTIME="$(nvim --clean --headless +'echo $VIMRUNTIME' +q 2>&1)" function _test_tz { # DST always in effect @@ -53,12 +54,19 @@ function test { } - function help { - echo "$0 " - echo "Tasks:" - compgen -A function | cat -n + echo "$0 " + echo "Tasks:" + compgen -A function | cat -n +} + +function format { + stylua lua/ tests/ +} + +function lint { + VIMRUNTIME=$VIMRUNTIME lua-language-server --configpath=../.luarc.jsonc --check=./ } TIMEFORMAT="Task completed in %3lR" -time ${@:-default} +time "${@:-default}" diff --git a/tests/dial/augend/hexcolor_spec.lua b/tests/dial/augend/hexcolor_spec.lua index 402d4f1..2ea465e 100644 --- a/tests/dial/augend/hexcolor_spec.lua +++ b/tests/dial/augend/hexcolor_spec.lua @@ -1,5 +1,6 @@ local hexcolor = require("dial.augend").hexcolor +---@param case colorcase? ---@return AugendHexColor local function create_augend(case) if case == nil then @@ -40,6 +41,7 @@ describe("Test of hex colors", function() it("rejects other values", function() assert.has_error(function() + ---@diagnostic disable-next-line: param-type-mismatch create_augend "invalid" end) end) diff --git a/tests/minimal_init.lua b/tests/minimal_init.lua index 0841a82..2bdbfb7 100644 --- a/tests/minimal_init.lua +++ b/tests/minimal_init.lua @@ -1,11 +1,11 @@ -local plenary_dir = os.getenv("PLENARY_DIR") or "/tmp/plenary.nvim" +local plenary_dir = os.getenv "PLENARY_DIR" or "/tmp/plenary.nvim" local is_not_a_directory = vim.fn.isdirectory(plenary_dir) == 0 if is_not_a_directory then - vim.fn.system({"git", "clone", "https://github.com/nvim-lua/plenary.nvim", plenary_dir}) + vim.fn.system { "git", "clone", "https://github.com/nvim-lua/plenary.nvim", plenary_dir } end -vim.opt.rtp:append(".") +vim.opt.rtp:append "." vim.opt.rtp:append(plenary_dir) -vim.cmd("runtime plugin/plenary.vim") -require("plenary.busted") +vim.cmd "runtime plugin/plenary.vim" +require "plenary.busted" From 26d85a4970ff659d2d559ad0eed30d50b7c011fa Mon Sep 17 00:00:00 2001 From: phanium <91544758+phanen@users.noreply.github.com> Date: Sat, 5 Jul 2025 22:42:25 +0800 Subject: [PATCH 2/3] chore: luacheck --- .luacheckrc | 19 +++++++++++++++++++ lua/dial/augend/case.lua | 5 +++-- lua/dial/augend/constant.lua | 7 +++---- lua/dial/augend/decimal_fraction.lua | 5 +++-- lua/dial/augend/integer.lua | 7 +++---- lua/dial/augend/misc.lua | 7 +++---- lua/dial/augend/paren.lua | 7 +++---- run | 4 ++-- 8 files changed, 39 insertions(+), 22 deletions(-) create mode 100644 .luacheckrc diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..56b0604 --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,19 @@ +read_globals = { "vim" } + +max_comment_line_length = false +codes = true + +exclude_files = {} + +ignore = { + "111", -- setting non-standard global variable + "113", -- accessing undefined variable + "211", -- unused function + "212", -- unused self + "311", -- unused variable + "431", -- shadow upvalue self + "542", -- empty if branch + "631", -- line is too long +} + +read_globals = { "vim" } diff --git a/lua/dial/augend/case.lua b/lua/dial/augend/case.lua index 9c66705..048b8cc 100644 --- a/lua/dial/augend/case.lua +++ b/lua/dial/augend/case.lua @@ -26,7 +26,7 @@ M.case_patterns["camelCase"] = { local ptr = 1 for i = 1, word:len(), 1 do local char = word:sub(i, i) - if not (char == char:lower()) then + if char ~= char:lower() then -- i 番目の文字が大文字の場合は直前で切る -- 小文字や数字などは切らない if i == 1 then @@ -67,7 +67,7 @@ M.case_patterns["PascalCase"] = { local ptr = 1 for i = 2, word:len(), 1 do local char = word:sub(i, i) - if not (char == char:lower()) then + if char ~= char:lower() then -- i 番目の文字が大文字の場合は直前で切る -- 小文字や数字などは切らない table.insert(subwords, word:sub(ptr, i - 1)) @@ -197,6 +197,7 @@ function M.new(config) config.types ) + -- luacheck: ignore -- local query = prefix .. util.if_expr(natural, "", "-?") .. "[" .. radix_to_query_character(radix) .. delimiter .. "]+" return setmetatable({ patterns = patterns, diff --git a/lua/dial/augend/constant.lua b/lua/dial/augend/constant.lua index 37c548d..fddde5c 100644 --- a/lua/dial/augend/constant.lua +++ b/lua/dial/augend/constant.lua @@ -82,9 +82,9 @@ end ---@param text string ---@param addend integer ----@param cursor? integer +---@param _cursor? integer ---@return addresult -function AugendConstant:add(text, addend, cursor) +function AugendConstant:add(text, addend, _cursor) local elements = self.config.elements local n_patterns = #elements local n = 1 @@ -133,8 +133,7 @@ function AugendConstant:add(text, addend, cursor) text = new_text end - cursor = #text - return { text = text, cursor = cursor } + return { text = text, cursor = #text } end M.alias = { diff --git a/lua/dial/augend/decimal_fraction.lua b/lua/dial/augend/decimal_fraction.lua index d869e8c..1f64a1e 100644 --- a/lua/dial/augend/decimal_fraction.lua +++ b/lua/dial/augend/decimal_fraction.lua @@ -90,9 +90,9 @@ end ---@param text string ---@param addend integer ----@param cursor? integer +---@param _cursor? integer ---@return addresult -function AugendDecimalFraction:add(text, addend, cursor) +function AugendDecimalFraction:add(text, addend, _cursor) local point_pos = text:find(self.point_char, 1, true) local int_part = text:sub(1, point_pos - 1) @@ -126,6 +126,7 @@ function AugendDecimalFraction:add(text, addend, cursor) local new_dec_part = str_num:sub(#str_num - #frac_part + 1) text = new_int_part .. "." .. new_dec_part + local cursor ---@type integer if self.digits_to_add == 0 then -- incremented integer part cursor = #new_int_part diff --git a/lua/dial/augend/integer.lua b/lua/dial/augend/integer.lua index fa56f1e..6f34c67 100644 --- a/lua/dial/augend/integer.lua +++ b/lua/dial/augend/integer.lua @@ -280,9 +280,9 @@ end ---@param text string ---@param addend integer ----@param cursor? integer +---@param _cursor? integer ---@return addresult -function AugendInteger:add(text, addend, cursor) +function AugendInteger:add(text, addend, _cursor) local n_prefix = #self.prefix local subtext = text:sub(n_prefix + 1) if self.delimiter ~= "" then @@ -319,8 +319,7 @@ function AugendInteger:add(text, addend, cursor) end text = self.prefix .. digits - cursor = #text - return { text = text, cursor = cursor } + return { text = text, cursor = #text } end M.alias = { diff --git a/lua/dial/augend/misc.lua b/lua/dial/augend/misc.lua index 6d2b72d..f59a3d6 100644 --- a/lua/dial/augend/misc.lua +++ b/lua/dial/augend/misc.lua @@ -18,9 +18,9 @@ M.alias.markdown_header = user.new { ---@param text string ---@param addend integer - ---@param cursor? integer + ---@param _cursor? integer ---@return addresult - add = function(text, addend, cursor) + add = function(text, addend, _cursor) local n = #text n = n + addend if n < 1 then @@ -30,8 +30,7 @@ M.alias.markdown_header = user.new { n = 6 end text = ("#"):rep(n) - cursor = 1 - return { text = text, cursor = cursor } + return { text = text, cursor = 1 } end, } diff --git a/lua/dial/augend/paren.lua b/lua/dial/augend/paren.lua index e351733..3915061 100644 --- a/lua/dial/augend/paren.lua +++ b/lua/dial/augend/paren.lua @@ -169,9 +169,9 @@ end ---@param text string ---@param addend integer ----@param cursor? integer +---@param _cursor? integer ---@return addresult -function AugendParen:add(text, addend, cursor) +function AugendParen:add(text, addend, _cursor) local n_patterns = #self.config.patterns local n = 1 for i, elem in ipairs(self.config.patterns) do @@ -201,8 +201,7 @@ function AugendParen:add(text, addend, cursor) local new_paren_close = new_paren_pair[2] text = new_paren_open .. text_inner .. new_paren_close - cursor = #text - return { text = text, cursor = cursor } + return { text = text, cursor = #text } end M.alias = { diff --git a/run b/run index 9aef23e..f01945e 100755 --- a/run +++ b/run @@ -2,7 +2,6 @@ TESTS_INIT=tests/minimal_init.lua TESTS_DIR=tests -VIMRUNTIME="$(nvim --clean --headless +'echo $VIMRUNTIME' +q 2>&1)" function _test_tz { # DST always in effect @@ -65,7 +64,8 @@ function format { } function lint { - VIMRUNTIME=$VIMRUNTIME lua-language-server --configpath=../.luarc.jsonc --check=./ + VIMRUNTIME="$(nvim --clean --headless +'echo $VIMRUNTIME' +q 2>&1)" lua-language-server --configpath=../.luarc.jsonc --check=./ + luacheck lua/ tests/ } TIMEFORMAT="Task completed in %3lR" From 9d0afc8e736a4128b3a8d4b15262a144eaba3f81 Mon Sep 17 00:00:00 2001 From: phanium <91544758+phanen@users.noreply.github.com> Date: Sat, 5 Jul 2025 22:44:07 +0800 Subject: [PATCH 3/3] ci: lint & format --- .github/workflows/test.yml | 43 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index df43d2a..bee8faa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,3 +20,46 @@ jobs: - name: run tests run: ./run test + + stylua: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: format + uses: JohnnyMorganz/stylua-action@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + version: latest + args: --check lua tests + + lint: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v4 + - uses: rhysd/action-setup-vim@v1 + with: + neovim: true + version: nightly + + - name: install lua-language-server + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + cd + gh release download -R sumneko/lua-language-server -p '*-linux-x64.tar.gz' -D lua-language-server + tar xzf lua-language-server/* -C lua-language-server + echo "${PWD}/lua-language-server/bin" >> $GITHUB_PATH + export PATH="${PWD}/lua-language-server/bin:${PATH}" + lua-language-server --version + + - name: install luacheck + run: | + sudo apt-get update + sudo apt-get install -y luarocks + sudo luarocks install luacheck + + - name: lint + run: ./run lint