1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
---@type string[][]
local dashboard = {}
---@type table<string,integer>
local _index = {
header = 1,
lazy = 2,
cowsay = 3,
}
---@type string[]
local sections = setmetatable({}, {
__index = function(_, k)
return dashboard[_index[k]]
end,
__newindex = function(_, k, v)
if _index[k] then
dashboard[_index[k]] = v
else
table.insert(dashboard, v)
_index[k] = #dashboard
end
vim.api.nvim_exec_autocmds("User", { pattern = "DashboardUpdate" })
end,
})
local function should_skip()
-- don't start when opening a file
if vim.fn.argc() > 0 then
return true
end
-- skip stdin
if vim.fn.line2byte(vim.fn.line("$")) ~= -1 then
return true
end
-- Handle nvim -M
if not vim.o.modifiable then
return true
end
for _, arg in pairs(vim.v.argv) do
-- whitelisted arguments
-- always open
if arg == "--startuptime" then
return false
end
-- blacklisted arguments
-- always skip
if
arg == "-b"
-- commands, typically used for scripting
or arg == "-c"
or vim.startswith(arg, "+")
or arg == "-S"
then
return true
end
end
-- base case: don't skip
return false
end
local function max_len(lines)
local max = 0
for _, line in ipairs(lines) do
max = math.max(max, vim.fn.strdisplaywidth(line))
end
return max
end
local function pad_lines(lines)
local max_line_len = max_len(lines)
local width = vim.api.nvim_win_get_width(0)
local padded = {}
for _, line in ipairs(lines) do
local line_len = max_line_len
local pad_len = math.floor((width / 2) - (line_len / 2))
table.insert(padded, string.rep(" ", pad_len) .. line)
end
return padded
end
local function render(buf)
local rendered = {}
for _, lines in pairs(dashboard) do
vim.list_extend(rendered, pad_lines(lines))
end
vim.bo[buf].modifiable = true
vim.api.nvim_buf_set_lines(buf, 0, -1, false, rendered)
vim.bo[buf].modifiable = false
end
if should_skip() then
return
end
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_set_current_buf(buf)
vim.opt_local.textwidth = 0
vim.opt_local.bufhidden = "wipe"
vim.opt_local.buflisted = false
vim.opt_local.matchpairs = ""
vim.opt_local.swapfile = false
vim.opt_local.buftype = "nofile"
vim.opt_local.filetype = "dashboard"
vim.opt_local.synmaxcol = 0
vim.opt_local.wrap = false
vim.opt_local.colorcolumn = ""
vim.opt_local.foldlevel = 999
vim.opt_local.foldcolumn = "0"
vim.opt_local.cursorcolumn = false
vim.opt_local.cursorline = false
vim.opt_local.number = false
vim.opt_local.relativenumber = false
vim.opt_local.list = false
vim.opt_local.spell = false
vim.opt_local.signcolumn = "no"
local function with_spacer(lines, count)
local spaced = lines
while #spaced < count do
table.insert(spaced, 1, "")
end
return spaced
end
local function cowsay()
local Job = require("plenary.job")
return Job:new({
command = "cowsay",
writer = Job:new({ command = "fortune", args = { "-s" } }),
}):sync()
end
local augroup = vim.api.nvim_create_augroup("dashboard", { clear = true })
vim.api.nvim_create_autocmd("User", {
group = augroup,
pattern = { "DashboardUpdate" },
callback = function()
if vim.api.nvim_get_current_buf() == buf then
render(buf)
end
end,
desc = "render dashboard on updates",
})
vim.api.nvim_create_autocmd("BufHidden", {
group = augroup,
pattern = { "*" },
callback = function(args)
if args.buf == buf then
vim.api.nvim_del_autocmd(augroup)
return true
end
end,
desc = "clear dashboard autocmds",
})
local c_ok, c_exe = pcall(vim.fn.executable, "cowsay")
local f_ok, f_exe = pcall(vim.fn.executable, "fortune")
if c_ok and 1 == c_exe and f_ok and 1 == f_exe then
sections.cowsay = with_spacer(cowsay(), 15)
vim.keymap.set("n", "<C-n>", function()
sections.cowsay = with_spacer(cowsay(), 15)
end, { desc = "next cowsay", buffer = buf })
end
sections.header = with_spacer({
" ",
" ███╗ ██╗███████╗ ██████╗ ██╗ ██╗██╗███╗ ███╗ ",
" ████╗ ██║██╔════╝██╔═══██╗██║ ██║██║████╗ ████║ ",
" ██╔██╗ ██║█████╗ ██║ ██║██║ ██║██║██╔████╔██║ ",
" ██║╚██╗██║██╔══╝ ██║ ██║╚██╗ ██╔╝██║██║╚██╔╝██║ ",
" ██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║ ",
" ╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═══╝ ╚═╝╚═╝ ╚═╝ ",
" ",
}, 15)
vim.api.nvim_create_autocmd("User", {
group = augroup,
pattern = { "Lazy*" },
callback = function()
local updates = nil
if require("lazy.status").has_updates() then
updates = string.format("updates: %s", require("lazy.status").updates())
end
local stats = require("lazy").stats()
sections.lazy = {
string.format("startup: %s ms", stats.startuptime),
string.format("plugins: %s (%s loaded)", stats.count, stats.loaded),
updates,
}
end,
desc = "dashboard lazy stats",
})
|