vim-startify icon indicating copy to clipboard operation
vim-startify copied to clipboard

Centralize splash screen horizontally

Open AndraSol opened this issue 4 years ago • 15 comments

First of all, thanks for this amazing VIM plugin. It is a simple but crazy useful idea, that brings VIM way closer to being a full IDE.

My only request/question: is there a way to have the splash screen auto centralized? When Vim or GVim are expanded, attached is an example of how it looks like. I find it particularly relevant because I set my GVim to re-display Startify whenever all buffers are closed.

Thanks a lot! startify-screen

AndraSol avatar Nov 19 '19 04:11 AndraSol

Unfortunately that's not easily possible right now. Startify adds lines one after the other. This is done on purpose, because then even when you have slow disk I/O or network drive access, you can actually see stuff happening when the Startify buffer is "loading".

For centralizing, all lines would have to be collected in a list first, because one have to find out the longest line. But given the slow I/O example, then, when using :Startify, one could have an empty buffer for seconds and the feeling of nothing happening while Startify is collecting.

You can set g:startify_left_padding, but that's far from being dynamic.

The design of adding lines one after the other won't change, but I try to think about this some more anyway. Maybe there's another way. (Ideas welcome!)

I would be possible to centralize after everything loaded normally, but then you would shortly see all lines on the left side before they get moved to the middle. This also involves resetting the syntax, because it relies on fixed columns. Probably not a nice experience.

mhinz avatar Nov 19 '19 11:11 mhinz

Hi, thanks for the really fast feedback!

I see your point and it does make sense. But I think there's a solution - you should not have to wait for all lines to be read before deciding on a left padding, simply because the centralization could be approximate. Here's my suggestion. Give users the option to specify the max characters the splash screen' width should have and then centralize based on that (in case users turn the option on). For example, suppose that I set in the config the splash screen to have 80 chars per line. Then, Startify could detect via code how many characters the current buffer is displaying horizontally. Say it is 105. Then, the left-padding is automatically set to int((105-80)/2). Sure, this has the caveat that lines longer than (for example) 80 chars would not be displayed in their entirety and could only have their hidden part see when one navigates to them and go to the right with the cursor. But this is true no matter what, if the Vim window has less width than the line. Also, since my suggestion is for that to be an optional feature, users will be obviously aware of the trade-off when choosing to set a "max_width" to their splash screen.

Alternatively, but less ideal, I do think your suggested workaround (centralize after reading the lines) could end up working, if it were an optional feature. For instance, if users don't have a problem with disk I/O, then having the read content centralized in the end could work well because in all cases I tried it reads really fast. Naturally, that would be an optional feature turned off by default. Another possible option is to also give the additional option of having Startify display its content only after everything is read and centralized.make possible to only display the content after it is all loaded (and centralized). I would certainly turn both on, since in my case at least Startify generates the splash screen really fast.

Let me know what you think.

AndraSol avatar Nov 19 '19 20:11 AndraSol

Let's just start playing around a bit! Have a look at https://github.com/mhinz/vim-startify/pull/401

It's just a proof of concept. Much left to improve.

mhinz avatar Nov 19 '19 22:11 mhinz

Wow, that was fast! So, let me thank you via testing and giving feedback. Just downloaded the files directly and tested. Up to specifying 80 chars, the line-centering works perfectly, with one exception: custom headers do not get aligned. Above 80 chars, the alignment becomes off, which is to be expected because then there is the natural extra space to the right due to no lines being long enough. See attached pics (first at 80, second at 120).

startify-screen2

startify-screen3

AndraSol avatar Nov 20 '19 01:11 AndraSol

Oh, also note that in your description given to the test branch you named the config option g:signify_center, while it is actually g:startify_center.

AndraSol avatar Nov 20 '19 01:11 AndraSol

Another feedback: while the centralization seems to work consistently in Vim, it is more inconsistent in gVim. By that I mean: in gVim, sometimes I open it and the splash screen is centralized, sometimes I open it and the splash screen is to the left.

AndraSol avatar Nov 20 '19 06:11 AndraSol

Just downloaded the files directly and tested.

😱Please use a plugin manager like vim-plug. Then you could just put Plug 'mhinz/vim-startify', {'branch': 'center'} in your vimrc.

Above 80 chars, the alignment becomes off, which is to be expected because then there is the natural extra space to the right due to no lines being long enough. See attached pics (first at 80, second at 120).

Yup, that's to be expected. I consider this a documentation issue. This is just an approximation, so people need to play around a bit to find their perfect value which probably is between 50 to 80.

custom headers do not get aligned

Right, I'll look into this.

Oh, also note that in your description given to the test branch you named the config option g:signify_center, while it is actually g:startify_center.

Oops! That's what you get for constantly switching between projects.

Another feedback: while the centralization seems to work consistently in Vim, it is more inconsistent in gVim. By that I mean: in gVim, sometimes I open it and the splash screen is centralized, sometimes I open it and the splash screen is to the left.

Hmm, I play around with it in my Ubuntu VM, but I guess somehow gVim's window size is changed at start, e.g. the window gets maximized? Could be a race issue.

mhinz avatar Nov 26 '19 16:11 mhinz

Ah, I just noticed that the "custom header not centered" issue is already solved. The startify#pad() helper function should be used (documented at :h g:startify_custom_header).

let g:startify_custom_header = 'startify#pad(startify#fortune#boxed())'

This makes the header use the exact same padding as the rest of the menu.

mhinz avatar Nov 26 '19 18:11 mhinz

Hi @mhinz, I was taking a look at this and found out that using let g:startify_lists causes the custom headers to not be centered.

Screen Shot 2019-12-15 at 20 20 06

I found it weird, as default headers were working just fine, so I took a look at the code and found a solution, here is my proposal:

  1. Change default lists to:
return [
          \ { 'header': ['MRU'],            'type': 'files' },
          \ { 'header': ['MRU '. getcwd()], 'type': 'dir' },
          \ { 'header': ['Sessions'],       'type': 'sessions' },
          \ { 'header': ['Bookmarks'],      'type': 'bookmarks' },
          \ { 'header': ['Commands'],       'type': 'commands' },
           \ ]

(Remove the s:padding_left)

  1. Change print_section_header function to:
" Function: s:print_section_header {{{1
function! s:print_section_header() abort
   $
   let curline = line('.')

   for lnum in range(curline, curline + len(s:last_message) + 1)
     call add(b:startify.section_header_lines, lnum)
   endfor

   for message in s:last_message
     call append('$', [s:padding_left . message])
   endfor
   call append('$', '')
   unlet s:last_message
 endfunction

This will cause the custom headers to work as expected (at least on my opinion)

Screen Shot 2019-12-15 at 20 30 39

This may not be the best approach 🤷‍♂

Tintef avatar Dec 15 '19 23:12 Tintef

Also, the custom header doesn't get centered, for that I found that this works:

Line 87-90:

" Must be global so that it can be read by syntax/startify.vim.
  let g:startify_header = exists('g:startify_custom_header')
          \ ? s:set_custom_section(startify#pad(g:startify_custom_header))
          \ : (exists('*strwidth') ? startify#pad(startify#fortune#cowsay()) : [])

Tintef avatar Dec 18 '19 19:12 Tintef

Alternatively, startify could display several columns to use the width: it does feel awkward to have all this right space empty.

teto avatar Jun 05 '20 13:06 teto

Any updates on this? I'm currently using the branch so I can use this feature... Custom headings not being aligned is what's annoying me right now though. I'd be glad to help if I get some pointers where to look.

jeyj0 avatar Jun 14 '20 11:06 jeyj0

I too would like to have this feature, it's not a deal breaker by any means, but it would help have a nicer feel. Thank you for this amazing "Dashboard"

stoicAlchemist avatar Nov 29 '20 17:11 stoicAlchemist

I'm looking forward to having this feature! I tried the center branch, but in my terminal, the text appears all the way to the right.

I was able to get some sort of centralization of the "splash screen" by using startify#center():

let g:startify_custom_header =
          \ 'startify#center(startify#fortune#cowsay())'
let g:startify_lists = [
    \ { 'type': 'dir',       'header': startify#center(['MRU '.getcwd()]) },
    \ { 'type': 'sessions',  'header': startify#center(['Sessions']) },
    \ { 'type': 'files',     'header': startify#center(['MRU']) },
    \ { 'type': 'bookmarks', 'header': startify#center(['Bookmarks']) },
    \ { 'type': 'commands',  'header': startify#center(['Commands']) },
    \ ]
let g:startify_padding_left = 68 " Hard coded padding for lists

PS: I changed the order of the lists.

marcoaaguiar avatar Jan 07 '21 14:01 marcoaaguiar

Not sure if this project is maintained so, after a lot of searching, I moved to using mini.starter. It recognised my sessions and got it to where I wanted with minimal configuration.

Screenshot 2022-05-01 at 16 44 09

My config:


local header_art = 
[[
 ╭╮╭┬─╮╭─╮┬  ┬┬╭┬╮
 │││├┤ │ │╰┐┌╯││││
 ╯╰╯╰─╯╰─╯ ╰╯ ┴┴ ┴
]]

-- using the mini plugins
require('mini.sessions').setup({
  -- Whether to read latest session if Neovim opened without file arguments
  autoread = false,
  -- Whether to write current session before quitting Neovim
  autowrite = false,
  -- Directory where global sessions are stored (use `''` to disable)
  directory =  '~/.vim/sessions', --<"session" subdir of user data directory from |stdpath()|>,
  -- File for local session (use `''` to disable)
  file = '' -- 'Session.vim',
})

local starter = require('mini.starter')
starter.setup({
  -- evaluate_single = true,
  items = {
    starter.sections.sessions(77, true),
    starter.sections.builtin_actions(),
  },
  content_hooks = {
    function(content)
      local blank_content_line = { { type = 'empty', string = '' } }
      local section_coords = starter.content_coords(content, 'section')
      -- Insert backwards to not affect coordinates
      for i = #section_coords, 1, -1 do
        table.insert(content, section_coords[i].line + 1, blank_content_line)
      end
      return content
    end,
    starter.gen_hook.adding_bullet("» "),
    starter.gen_hook.aligning('center', 'center'),
  },
  header = header_art,
  footer = '',
})

Apologies for being off topic in regards to the current repo but I thought it may be useful to someone.

dathinaios avatar May 01 '22 13:05 dathinaios