Skip to content

Commit 63e83ad

Browse files
authored
feat(doom): Add vertical center (#476)
* refactor(doom): Add load_packages function. Rename elements * refactor(doom): Split center_entry_list into its own function. * feat(doom)!: Center the dashboard on the vertical (`vertical_center`) To disable this add `vertical_center = false` in the doom `configs` * fix(doom): Fix center generation without a config * feat(doom): Change `vertical_center` to be opt-in
1 parent 2f641b0 commit 63e83ad

File tree

2 files changed

+103
-44
lines changed

2 files changed

+103
-44
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ config = {
123123
},
124124
},
125125
footer = {},
126+
vertical_center = false, -- Center the Dashboard on the vertical (from top to bottom)
126127
}
127128
```
128129

@@ -145,7 +146,7 @@ DashboardHeader DashboardFooter
145146
-- Hyper theme
146147
DashboardProjectTitle DashboardProjectTitleIcon DashboardProjectIcon
147148
DashboardMruTitle DashboardMruIcon DashboardFiles DashboardShortCutIcon
148-
-- Doome theme
149+
-- Doom theme
149150
DashboardDesc DashboardKey DashboardIcon DashboardShortCut
150151
```
151152

lua/dashboard/theme/doom.lua

Lines changed: 101 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
local api, keymap = vim.api, vim.keymap
22
local utils = require('dashboard.utils')
33

4-
local function generate_center(config)
4+
local vert_offset
5+
6+
local function gen_center_icons_and_descriptions(config)
57
local lines = {}
68
local center = config.center
7-
or {
8-
{ desc = 'Please config your own center section', key = 'p' },
9-
}
109

1110
local counts = {}
1211
for _, item in pairs(center) do
@@ -47,21 +46,19 @@ local function generate_center(config)
4746
lines[i] = lines[i]:sub(1, #lines[i] - count)
4847
end
4948

50-
local first_line = api.nvim_buf_line_count(config.bufnr)
51-
api.nvim_buf_set_lines(config.bufnr, first_line, -1, false, lines)
52-
53-
if not config.center then
54-
return
55-
end
49+
api.nvim_buf_set_lines(config.bufnr, vert_offset, -1, false, lines)
50+
return lines
51+
end
5652

53+
local function gen_center_highlights_and_keys(config, lines)
5754
local ns = api.nvim_create_namespace('DashboardDoom')
5855
local seed = 0
59-
local pos_map = {}
56+
local position_map = {}
6057
for i = 1, #lines do
6158
if lines[i]:find('%w') then
6259
local idx = i == 1 and i or i - seed
6360
seed = seed + 1
64-
pos_map[i] = idx
61+
position_map[i] = idx
6562
local _, scol = lines[i]:find('%s+')
6663
local ecol = scol + (config.center[idx].icon and #config.center[idx].icon or 0)
6764

@@ -70,7 +67,7 @@ local function generate_center(config)
7067
config.bufnr,
7168
0,
7269
config.center[idx].icon_hl or 'DashboardIcon',
73-
first_line + i - 1,
70+
vert_offset + i - 1,
7471
0,
7572
ecol
7673
)
@@ -80,7 +77,7 @@ local function generate_center(config)
8077
config.bufnr,
8178
0,
8279
config.center[idx].desc_hl or 'DashboardDesc',
83-
first_line + i - 1,
80+
vert_offset + i - 1,
8481
ecol,
8582
-1
8683
)
@@ -94,45 +91,61 @@ local function generate_center(config)
9491
string.format(config.center[idx].key_format or ' [%s]', config.center[idx].key),
9592
config.center[idx].key_hl or 'DashboardKey',
9693
})
97-
api.nvim_buf_set_extmark(config.bufnr, ns, first_line + i - 1, 0, {
94+
api.nvim_buf_set_extmark(config.bufnr, ns, vert_offset + i - 1, 0, {
9895
virt_text_pos = 'eol',
9996
virt_text = virt_tbl,
10097
})
10198
end
10299
end
103100
end
101+
return position_map
102+
end
104103

105-
local line = api.nvim_buf_get_lines(config.bufnr, first_line, first_line + 1, false)[1]
104+
local function gen_center_base(config)
105+
if not config.center then
106+
local msg = utils.center_align({ 'Please config your own center section', '' })
107+
api.nvim_buf_set_lines(config.bufnr, vert_offset, -1, false, msg)
108+
return {}
109+
end
110+
111+
local lines = gen_center_icons_and_descriptions(config)
112+
return lines
113+
end
114+
115+
local function move_cursor_behaviour(config, bottom_linenr)
116+
local line = api.nvim_buf_get_lines(config.bufnr, vert_offset, vert_offset + 1, false)[1]
106117
local col = line:find('%w')
107118
local col_width = api.nvim_strwidth(line:sub(1, col))
108119
col = col and col - 1 or 9999
109-
api.nvim_win_set_cursor(config.winid, { first_line + 1, col })
120+
api.nvim_win_set_cursor(config.winid, { vert_offset + 1, col })
110121

111-
local bottom = api.nvim_buf_line_count(config.bufnr)
112122
vim.defer_fn(function()
113123
local before = 0
114124
if api.nvim_get_current_buf() ~= config.bufnr then
115125
return
116126
end
127+
128+
local dashboard_group = api.nvim_create_augroup('DashboardDoomCursor', { clear = true })
117129
api.nvim_create_autocmd('CursorMoved', {
118130
buffer = config.bufnr,
131+
group = dashboard_group,
119132
callback = function()
120133
local buf = api.nvim_win_get_buf(0)
121134
if vim.api.nvim_get_option_value('filetype', { buf = buf }) ~= 'dashboard' then
122135
return
123136
end
124137

125138
local curline = api.nvim_win_get_cursor(0)[1]
126-
if curline < first_line + 1 then
127-
curline = bottom - 1
128-
elseif curline > bottom - 1 then
129-
curline = first_line + 1
139+
if curline < vert_offset + 1 then
140+
curline = bottom_linenr - 1
141+
elseif curline > bottom_linenr - 1 then
142+
curline = vert_offset + 1
130143
elseif not api.nvim_get_current_line():find('%w') then
131144
curline = curline + (before > curline and -1 or 1)
132145
end
133146
before = curline
134147

135-
-- FIX: #422: In Lua the length of a string is the number of bytes not
148+
-- NOTE: #422: In Lua the length of a string is the number of bytes not
136149
-- the number of characters.
137150
local curline_str = api.nvim_buf_get_lines(config.bufnr, curline - 1, curline, false)[1]
138151
local strwidth = api.nvim_strwidth(curline_str:sub(1, col + 1))
@@ -144,10 +157,12 @@ local function generate_center(config)
144157
end,
145158
})
146159
end, 0)
160+
end
147161

162+
local function confirm_key(config, position_map)
148163
keymap.set('n', config.confirm_key or '<CR>', function()
149164
local curline = api.nvim_win_get_cursor(0)[1]
150-
local index = pos_map[curline - first_line]
165+
local index = position_map[curline - vert_offset]
151166
if index and config.center[index].action then
152167
if type(config.center[index].action) == 'string' then
153168
local dump = loadstring(config.center[index].action)
@@ -165,13 +180,18 @@ local function generate_center(config)
165180
end, { buffer = config.bufnr, nowait = true, silent = true })
166181
end
167182

168-
local function generate_footer(config)
169-
local first_line = api.nvim_buf_line_count(config.bufnr)
183+
local function load_packages(config)
184+
local packages = config.packages or {
185+
enable = true,
186+
}
187+
if not packages.enable then
188+
return
189+
end
190+
170191
local package_manager_stats = utils.get_package_manager_stats()
171-
local footer = {}
192+
local lines = {}
172193
if package_manager_stats.name == 'lazy' then
173-
footer = {
174-
'',
194+
lines = {
175195
'',
176196
'Startuptime: ' .. package_manager_stats.time .. ' ms',
177197
'Plugins: '
@@ -181,39 +201,77 @@ local function generate_footer(config)
181201
.. ' installed',
182202
}
183203
else
184-
footer = {
204+
lines = {
185205
'',
186206
'neovim loaded ' .. package_manager_stats.count .. ' plugins',
187207
}
188208
end
209+
210+
local first_line = api.nvim_buf_line_count(config.bufnr)
211+
api.nvim_buf_set_lines(config.bufnr, first_line, -1, false, utils.center_align(lines))
212+
213+
for i, _ in pairs(lines) do
214+
api.nvim_buf_add_highlight(config.bufnr, 0, 'Comment', first_line + i - 1, 0, -1)
215+
end
216+
217+
return lines
218+
end
219+
220+
local function gen_footer(config)
221+
local lines = {} ---@type table?
189222
if config.footer then
190223
if type(config.footer) == 'function' then
191-
footer = config.footer()
224+
lines = config.footer()
192225
elseif type(config.footer) == 'string' then
193226
local dump = loadstring(config.footer)
194227
if dump then
195-
footer = dump()
228+
lines = dump()
196229
end
197230
elseif type(config.footer) == 'table' then
198-
footer = config.footer
231+
lines = config.footer
199232
end
233+
local first_line = api.nvim_buf_line_count(config.bufnr)
234+
api.nvim_buf_set_lines(config.bufnr, first_line, -1, false, utils.center_align(lines))
235+
for i = 1, #lines do
236+
api.nvim_buf_add_highlight(config.bufnr, 0, 'DashboardFooter', first_line + i - 1, 0, -1)
237+
end
238+
else
239+
lines = load_packages(config)
200240
end
201-
api.nvim_buf_set_lines(config.bufnr, first_line, -1, false, utils.center_align(footer))
202-
for i = 1, #footer do
203-
api.nvim_buf_add_highlight(config.bufnr, 0, 'DashboardFooter', first_line + i - 1, 0, -1)
241+
utils.add_update_footer_command(config.bufnr, lines)
242+
return #lines
243+
end
244+
245+
local function vertical_center(config)
246+
if config.vertical_center ~= true then
247+
return
204248
end
205249

206-
utils.add_update_footer_command(config.bufnr, footer)
250+
local size = math.floor(vim.o.lines / 2)
251+
- math.ceil(api.nvim_buf_line_count(config.bufnr) / 2)
252+
- 2
253+
local fill = utils.generate_empty_table(size)
254+
api.nvim_buf_set_lines(config.bufnr, 0, 0, false, fill)
255+
256+
vert_offset = vert_offset + (size < 0 and 0 or size)
207257
end
208258

209-
---@private
210259
local function theme_instance(config)
211260
require('dashboard.theme.header').generate_header(config)
212-
generate_center(config)
213-
generate_footer(config)
214-
api.nvim_set_option_value('modifiable', false, { buf = config.bufnr })
215-
api.nvim_set_option_value('modified', false, { buf = config.bufnr })
216-
--defer until next event loop
261+
vert_offset = api.nvim_buf_line_count(config.bufnr)
262+
263+
local lines = gen_center_base(config)
264+
local footer_size = gen_footer(config)
265+
vertical_center(config)
266+
local actions_position_map = gen_center_highlights_and_keys(config, lines)
267+
268+
local last_entry_pos = api.nvim_buf_line_count(config.bufnr) - footer_size
269+
move_cursor_behaviour(config, last_entry_pos)
270+
confirm_key(config, actions_position_map)
271+
272+
vim.bo[config.bufnr].modifiable = false
273+
vim.bo[config.bufnr].modified = false
274+
-- defer until next event loop
217275
vim.schedule(function()
218276
api.nvim_exec_autocmds('User', {
219277
pattern = 'DashboardLoaded',

0 commit comments

Comments
 (0)