irongit

A Neovim plugin enabling you to solve LeetCode problems.

166 lines4.2 KBLua
1local O = require("nui.object")
2local log = require("leetcode.logger")
3local config = require("leetcode.config")
4
5---@class lc-ui.Utils
6local utils = {}
7
8---@param tbl table
9function utils.shallowcopy(tbl)
10 local new_tbl = {}
11 for _, value in ipairs(tbl) do
12 table.insert(new_tbl, value)
13 end
14
15 return new_tbl
16end
17
18---@param item lc.ui.Lines
19function utils.longest_line(item)
20 if item.class.name == "LeetLine" then
21 return vim.api.nvim_strwidth(item:content())
22 end
23
24 local max_len = 0
25 for _, line in pairs(item:contents()) do
26 max_len = math.max(utils.longest_line(line), max_len)
27 end
28
29 return max_len
30end
31
32---@param diff string
33function utils.diff_to_hl(diff)
34 local hl = {
35 all = "leetcode_all",
36
37 easy = "leetcode_easy",
38 fundamental = "leetcode_easy",
39
40 medium = "leetcode_medium",
41 intermediate = "leetcode_medium",
42
43 hard = "leetcode_hard",
44 advanced = "leetcode_hard",
45 }
46
47 return hl[diff:lower()] or ""
48end
49
50---@param status string
51function utils.status_to_hl(status)
52 if not status then
53 return
54 end
55
56 return table.unpack(config.icons.hl.status[status])
57end
58
59---@param layout lc.ui.Renderer
60function utils.win_width(layout)
61 if not (layout.winid and vim.api.nvim_win_is_valid(layout.winid)) then
62 return 0
63 end
64 return vim.api.nvim_win_get_width(layout.winid)
65end
66
67---@param lines lc.ui.Lines
68---@param layout lc.ui.Renderer
69---
70---@return string
71function utils.get_padding(lines, layout)
72 local opts = lines._.opts
73 local padding = ""
74
75 -- if type(opts.padding.left) == "string" then
76 -- padding = opts.padding.left
77 -- elseif type(opts.padding.left) == "number" then
78 -- padding = (" "):rep(opts.padding.left)
79 -- end
80
81 if type(opts.padding.left) == "string" then
82 padding = padding .. opts.padding.left
83 elseif type(opts.padding.left) == "number" then
84 padding = padding .. (" "):rep(opts.padding.left)
85 end
86
87 local position = opts.position
88 if position ~= "left" and vim.api.nvim_win_is_valid(layout.winid or -1) then
89 local max_len = utils.longest_line(lines)
90 local win_width = utils.win_width(layout)
91
92 if position == "center" then
93 local mid = (win_width - max_len) / 2
94 local spaces = (" "):rep(mid)
95 padding = spaces
96 elseif position == "right" then
97 local mid = win_width - max_len - 1
98 local spaces = (" "):rep(mid)
99 padding = spaces
100 end
101 end
102
103 return padding
104end
105
106function utils.buf_set_opts(bufnr, options)
107 if not vim.api.nvim_buf_is_valid(bufnr) then
108 return
109 end
110
111 for opt, value in pairs(options) do
112 local ok, err = pcall(vim.api.nvim_set_option_value, opt, value, { buf = bufnr })
113 if not ok then
114 log.error(err)
115 end
116 end
117end
118
119function utils.win_set_opts(winid, options)
120 if not vim.api.nvim_win_is_valid(winid) then
121 return
122 end
123
124 for opt, value in pairs(options) do
125 local ok, err =
126 pcall(vim.api.nvim_set_option_value, opt, value, { win = winid, scope = "local" })
127 if not ok then
128 log.error(err)
129 end
130 end
131end
132
133---@param winid number
134function utils.win_set_winfixbuf(winid)
135 local u = require("leetcode.utils")
136 u.with_version("0.10.0", function()
137 utils.win_set_opts(winid, { winfixbuf = true })
138 end)
139end
140
141---@param winid number
142---@param bufnr number
143---@param force? boolean
144function utils.win_set_buf(winid, bufnr, force)
145 local u = require("leetcode.utils")
146
147 u.with_version("0.10.0", function()
148 local wfb = vim.api.nvim_win_get_option(winid, "winfixbuf")
149
150 if not wfb then
151 vim.api.nvim_win_set_buf(winid, bufnr)
152 elseif force then
153 utils.win_set_opts(winid, { winfixbuf = false })
154 vim.api.nvim_win_set_buf(winid, bufnr)
155 utils.win_set_opts(winid, { winfixbuf = true })
156 end
157 end, function()
158 vim.api.nvim_win_set_buf(winid, bufnr)
159 end)
160end
161
162function utils.is_instance(instance, class)
163 return type(instance) == "table" and O.is_instance(instance, class)
164end
165
166return utils