onivim / oni

Oni: Modern Modal Editing - powered by Neovim
https://www.onivim.io
MIT License
11.35k stars 299 forks source link

Feature: Session Management / Persistence #1225

Open bryphe opened 6 years ago

bryphe commented 6 years ago

Session persistence / management is a feature that's been asked for a few times. Vim / Neovim luckily have some great session management tooling built-in - like mksession. In addition, there may be some particular UI state we should persist as well.

IMO, a reasonable default is to persist the session state when closing - we should give the IEditors a chance to persist any data that they need, and be able to rehydrate that on load.

Opening this up for feedback / ideas, as it's been requested a few times 😄

akinsho commented 6 years ago

@bryphe love this idea and I personally depend heavily on this feature, I use startify which also serves as a start screen but might not be ideal for this, a question I have here is whether this would be managed manually i.e. an oni plugin or addition to the oni workspace api which called mksession and saved them to a dir then perhaps the start screen could read in the available sessions and on click/select opens the session?. Another alternative could be to use an existing plugin which has already been created a great example is the indomitable Tpope's Vim-obsession.

His list of requirements and reasons for implementing obsession are a very good recipe for the requirements of this sort of functionality.

If doing this manually a thought here could be an oni plugin which is essentially a wrapper around calling :mksession prompting the user with a name for the session and saving it to a common directory which can then be accessed to list the available sessions. Obsession also automatically persists and updates sessions on BufEnter and on VimLeave so its all automatically managed.

Here's how startify's implementation of this looks:

screen shot 2018-01-04 at 10 05 21
hoschi commented 6 years ago

prompting the user with a name for the session

Would be cool to save the session for current branch name. I hacked that together in my init.vim (never finished it :disappointed: ) and really happy since I have this (even as unstable it is).

akinsho commented 6 years ago

theres vim plugins for that in the interim @hoschi vim-promiscuous and one by tweekmonster forgot its name though.

hoschi commented 6 years ago

@Akin909 Ah yeah, forgot that my code was to bring CtrlSpace into the mix. Because I need "per tab buffer list". When "tab" is a container for windows, this makes so much sense :laughing:

For the record:

"--------------------
"vim-promiscuous
"--------------------

" The callback used to load a session (receives branch name)
let g:promiscuous_load = 'LoadCtrlSpaceWorkspaceForBranchName'

" The prefix prepended to all commit, stash, and log messages
let g:promiscuous_prefix = '[Promiscuous]'

" The callback used to save a session (receives branch name)
let g:promiscuous_save = 'ctrlspace#workspaces#SaveWorkspace'

" It's recommended to make a custom key binding for this. I've been using the following mapping:
nmap <leader>gb :Promiscuous<cr>

" I also use an additional mapping to checkout the previous branch (usually master):
"nmap <leader>gg :Promiscuous -<cr>

function! LoadCtrlSpaceWorkspaceForBranchName(branchName)
    " clear ctrlp cache
    CtrlPClearAllCaches

    " get branch name and workspaces
    let branchName = a:branchName
    let workspaces = ctrlspace#workspaces#Workspaces()
    if empty(workspaces)
        " init workspaces
        call ctrlspace#workspaces#SetWorkspaceNames()
        let workspaces = ctrlspace#workspaces#Workspaces()
    endif

    " search, load if found
    for existingName in workspaces
        if branchName ==# existingName
            return ctrlspace#workspaces#LoadWorkspace(0, branchName)
        endif
    endfor

    " save empty session as new one
    return ctrlspace#workspaces#SaveWorkspace(branchName)
endfunction

function! CreateCtrlSpaceWorkspaceForCurrentBranchName()
    let branchName = promiscuous#git#branch()
    " save current session with branch name
    return ctrlspace#workspaces#SaveWorkspace(branchName)
endfunction

function! LoadCtrlSpaceWorkspaceForCurrentBranchName()
    let branchName = promiscuous#git#branch()
    return LoadCtrlSpaceWorkspaceForBranchName(branchName)
endfunction

function! SafetyCheckBeforeBranchCheckout()
    let branchName = promiscuous#git#branch()

    let isSession = ctrlspace#workspaces#ActiveWorkspace().Status
    " check if a session is active
    " check if session name matches branch name
    "
    " confirm befor switching
    " ctrlspace#ui#Confirmed
    "
    " call promiscuous command
endfunction

" when created new feature, save current session for new branch name
nmap <leader>sw :call CreateCtrlSpaceWorkspaceForCurrentBranchName()<cr>

" init fresh nvim instance with session for current branch
nmap <leader>lw :call LoadCtrlSpaceWorkspaceForCurrentBranchName()<cr>
tarciozemel commented 6 years ago

To start, an Oni config to only keeping the existing opened files in tabs/windows would be veeery nice. :grimacing: