mhinz / vim-startify

:link: The fancy start screen for Vim.
MIT License
5.3k stars 186 forks source link

[Feature Request] Option to auto create initial session #354

Closed stratumforce closed 5 years ago

stratumforce commented 5 years ago

After working another two hours on a new project and forgetting to run :SSave (again!) I think this could be very useful option.

I'm new to Vim, still searching for useful plugins and this is definitely one of them for me! Especially using it for every project that I'm working on. And sometimes I'm just forgetting to create a session.

I have .nvimrc file that I copy around my projects and it contains this:

let g:startify_session_dir = '.vim/session'

Spend an hour trying to create this initial session myself and achieved it with this code:

if !filereadable('.vim/session/session.vim')
  silent execute "!mkdir -p .vim/session"
  silent call startify#session_write('.vim/session/session.vim')
endif

It works. But looks hacky. I think this could be implemented in this project to have a simple option like startify_session_autocreate = 1 with respect to startify_session_dir. Just create Session.vim in startify_session_dir or if there's no such option set create session file in default ~/.vim/session if it not exists already.

I think this could be useful mostly for people that uses this plugin for every project that they're working on. Not sure if there's the need to use this system-wide.

mhinz commented 5 years ago

I have .nvimrc file that I copy around my projects

You mean init.vim? nvimrc is outdated for years already. :)

if !filereadable('.vim/session/session.vim')
  silent execute "!mkdir -p .vim/session"
  silent call startify#session_write('.vim/session/session.vim')
endif

To be honest, your use case seems rather uncommon and since I'm reluctant to add any more options without a very good reason (there are too many already) and the fact that this plugin is not meant to a plugin for managing sessions (this functions are there for conveniently writing sessions to always the same directory so that the Startify buffer can list them), I won't introduce a new option for this.

For the reason above, I'm closing this. But if you need further help with your custom code, I'll gladly help!

stratumforce commented 5 years ago

You mean init.vim? nvimrc is outdated for years already. :)

No, it's actually .nvimrc. I have ~/.config/nvim/init.vim that includes ~/.vimrc in which I have this options:

set exrc
set secure

set exrc sources .nvimrc for Neovim or .vimrc for Vim if there is such file in directory in which I run $ nvim or $ vim.

  • With this code unguarded in your vimrc, you have to pay a lot of attention to where you even start Nvim because otherwise you'd litter your disk with relative .vim/session paths.
  • Then, if you just use nvim in the shell it starts with an empty buffer and your code creates a session for that. How does that help against forgetting :SSave? It would need at least g:startify_session_persistence to be enabled.

The code that I mentioned I only have in that .nvimrc in project folder, not in ~/.vimrc. So no worries for me having my diks littered. And I do have g:startify_session_persistence in ~/.vimrc.

I see your point. I agree that this is an uncommon use case. But there is another thing that would be nice to have in this plugin. For now the session automatically saves only in case of leaving vim or loading new session. And if my PC/laptop somehow crashes or electricity went off while I work on PC or maybe even crash of Vim/Neovim itself than this session won't be saved. I think there should be some timer for autosaving feature or just autosave when new buffer or tab is opened. I'm not sure yet how vim-obsession is implemented, maybe it could solve this problem or maybe I'll just could add another function to my .nvimrc to save sessions automatically. But since you're already have some session management in this plugin I think this would be useful to implement rather than including yet another plugin.

Anyway, thanks for your reply!

mhinz commented 5 years ago

But since you're already have some session management in this plugin I think this would be useful to implement rather than including yet another plugin.

No. :) I regret that I added so many session-related things to this plugin already, because for this very reason. It's like two plugins in one and now people expect me to improve on both of them.

I think there should be some timer for autosaving feature or just autosave when new buffer or tab is opened.

IMHO, the event-based approach is more useful than an arbitrary timer, although the latter would not be hard to implement either. I suggest something like this in your main vimrc:

function! s:save_session() abort
  if !empty(v:this_session) && get(g:, 'startify_session_persistence')
    call startify#session_write(v:this_session)
  endif
endfunction

autocmd BufNewFile,BufAdd,BufDelete,BufLeave * call s:save_session()

Maybe even on :h BufWritePost. (v:this_session is set to the .vim/session/session.vim in this case.)

stratumforce commented 5 years ago

I agree, the event-based approach is much better. I looked at vim-obsession implementation and found out that it saves session on BufEnter. Tried your approach first with BufNewFile,... with some logging and having session with 3 buffers this code would save the session 5 times while opening. With autocmd BufEnter * ... session saves just once and works just enough: saving on switching buffers, opening new buffer, deleting buffer.

Though there's problems if NERDtree is opened (which I actually don't use much). In startify's docs there's this code:

let g:startify_session_before_save = [
        \ 'echo "Cleaning up before saving.."',
        \ 'silent! NERDTreeTabsClose'
        \ ]

Found out that this doesn't work because it should be NERDTreeClose and not NERDTreeTabsClose. And NERDTree will try to open after quitting nvim and reopening the last session. As for autosaving: this would close NERDTree right on opening it along with the buffer from which it was called. This is ugly. I think I'll just have to remove NERDTreeClose command from startify_session_before_save and close NERDTree manually after session load.

Maybe I'll try vim-obsession and vim-prosession which extends tpope's plugin and allows creating default session. Just to see how they work and if it's possible to manage them to work with vim-startify. Probably have to disable startify_session_persistence and use startify just as the start screen as it was intended.

Anyway, thanks so much for your help! Today I learned about vim scripting :)

stratumforce commented 5 years ago

I finally managed to do what I need. I added plugin vim-obsession, disabled startify_session_persistance and have this code in my .nvimrc file:

let g:startify_session_dir = '.vim/session'
let s:my_session_name = 'session.vim'
let s:my_session_full_path = g:startify_session_dir . '/' . s:my_session_name

if !filereadable(s:my_session_full_path)
  silent execute "!mkdir -p " . g:startify_session_dir
  silent call startify#session_write(s:my_session_full_path)
endif

function! s:ObsessIt()
  if ObsessionStatus() == '[S]'
    execute "Obsession"
  endif
endfunction

autocmd SessionLoadPost * call s:ObsessIt()

This code, when nvim first executed in project folder, creates dummy session using the path and session name that I provided. Then I have startify start screen with the session already listed. Selecting the session and after the session is loaded nvim checking if Obsession is activated (it gives two codes: [$] if it is and [S] if it's not) and activates it if needed. vim-obsession handles the session by itself placing 3 variables in session.vim:

let g:this_session = v:this_session
let g:this_obsession = v:this_session
let g:this_obsession_status = 2

And with the second launch of this session obsession is already working and saving session on every BufEnter. So I have vim-startify as a start screen and a session loader and vim-obsession saving sessions automatically with event-based approach. Finally happy with this setup!