馃 a tiny, customizable statusline for neovim
1local utils = {}
2
3function utils.get_client()
4 local buf_ft = vim.api.nvim_get_option_value("filetype", { buf = 0 })
5 local result = vim.iter(vim.lsp.get_clients({ bufnr = 0 })):find(function(
6 client --[[@as vim.lsp.Client]]
7 )
8 return vim.iter(ipairs(client.config.filetypes)):any(function(_, ft)
9 return ft == buf_ft
10 end)
11 end)
12 if result then
13 return result.config.name
14 end
15end
16
17--- flatten list so all children have level of depth
18---@param lst table
19---@param maxdepth integer
20function utils.flatten(lst, maxdepth)
21 ---@param _t any[]
22 ---@return integer
23 local function _depth(_t)
24 return vim.iter(_t):fold(1, function(maxd, v)
25 if type(v) == "table" then
26 local d = 1 + _depth(v)
27 if d > maxd then
28 return d
29 end
30 end
31 return maxd
32 end)
33 end
34
35 local result = {}
36 ---@param _t any[]
37 local function _flatten(_t)
38 local n = #_t
39 for i = 1, n do
40 local v = _t[i]
41 if type(v) ~= "table" or _depth(v) <= maxdepth then
42 table.insert(result, v)
43 else
44 _flatten(v)
45 end
46 end
47 end
48 _flatten(lst)
49 return result
50end
51
52function utils.getfilename()
53 local _, default_file_hl = require("mini.icons").get("default", "file")
54
55 local name = vim.fn.expand("%:t")
56
57 local file_icon_raw, file_icon_hl
58
59 if vim.bo.buftype ~= "" then
60 local filetype = vim.bo.filetype
61 file_icon_raw, file_icon_hl = require("mini.icons").get("filetype", filetype)
62 else
63 file_icon_raw, file_icon_hl = require("mini.icons").get("file", name)
64 end
65
66 return { { name, default_file_hl }, { " " }, { file_icon_raw, file_icon_hl } }
67end
68
69function utils.getfilepath()
70 local path = vim.fn.expand("%:p:~:.")
71
72 local file_path_list = {}
73 local _ = string.gsub(path, "[^/]+", function(w)
74 table.insert(file_path_list, w)
75 end)
76
77 local filepath = vim.iter(ipairs(file_path_list)):fold("", function(acc, i, fragment)
78 if i == #file_path_list then
79 return acc
80 end
81 acc = acc .. fragment .. "/"
82 return acc
83 end)
84
85 return { filepath, "Directory" }
86end
87
88function utils.get_searchcount()
89 local result = vim.fn.searchcount({ recompute = 1 })
90 if vim.v.hlsearch ~= 1 then
91 return ""
92 end
93 if vim.tbl_isempty(result) then
94 return ""
95 end
96 local term = vim.fn.getreg("/")
97 local display
98 if result.incomplete == 1 then
99 -- timed out
100 display = "[?/??]"
101 elseif result.incomplete == 2 then
102 -- max count exceeded
103 if result.total > result.maxcount and result.current > result.maxcount then
104 display = string.format("[>%d/>%d]", result.current, result.total)
105 elseif result.total > result.maxcount then
106 display = string.format("[%d/>%d]", result.current, result.total)
107 end
108 end
109 display = display or string.format("[%d/%d]", result.current, result.total)
110
111 return { { string.format("/%s", term), "IncSearch" }, { " " }, { display, "MsgSeparator" } }
112end
113
114---@param mode string
115---@return string
116function utils.get_modehl_name(mode)
117 return "@lylla." .. mode
118end
119
120---@return string
121function utils.get_modehl()
122 local mode = vim.api.nvim_get_mode().mode
123
124 if string.match(mode, "n") then
125 return utils.get_modehl_name("normal")
126 end
127
128 if string.match(mode, "[vVs]") then
129 return utils.get_modehl_name("visual")
130 end
131
132 if string.match(mode, "c") then
133 return utils.get_modehl_name("command")
134 end
135
136 if string.match(mode, "[irRt]") then
137 return utils.get_modehl_name("insert")
138 end
139
140 return mode
141end
142
143return utils