11local api , keymap = vim .api , vim .keymap
22local 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 })
166181end
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 )
207257end
208258
209- --- @private
210259local 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