开发者

How to auto save vim session on quit and auto reload on start including split window state?

I like to split my vim screen in 3. one :vsplit and one :split开发者_运维知识库. I want these windows and the files I worked on to be saved when I close vim. I also want these windows to automatically load when I start vim.

I tried to install gsessions (just added the file to the plugin folder), but nothing happend. I am new to vim so I don't know exactly how the configuration works.


I modified 2ck's script slightly to save a .session.vim in your current working directory instead of the directory where your current open file is in.

Also, it checks if the file exists before sourcing it.

fu! SaveSess()
    execute 'mksession! ' . getcwd() . '/.session.vim'
endfunction

fu! RestoreSess()
if filereadable(getcwd() . '/.session.vim')
    execute 'so ' . getcwd() . '/.session.vim'
    if bufexists(1)
        for l in range(1, bufnr('$'))
            if bufwinnr(l) == -1
                exec 'sbuffer ' . l
            endif
        endfor
    endif
endif
endfunction

autocmd VimLeave * call SaveSess()
autocmd VimEnter * nested call RestoreSess()


You can do per directory sessions with this is your vimrc:

fu! SaveSess()
    execute 'call mkdir(%:p:h/.vim)'
    execute 'mksession! %:p:h/.vim/session.vim'
endfunction

fu! RestoreSess()
execute 'so %:p:h/.vim/session.vim'
if bufexists(1)
    for l in range(1, bufnr('$'))
        if bufwinnr(l) == -1
            exec 'sbuffer ' . l
        endif
    endfor
endif
endfunction

autocmd VimLeave * call SaveSess()
autocmd VimEnter * call RestoreSess()

That will litter your directories with .vim s, but you can easily modify that. Also, change sbuffer to badd if you don't want new windows for each file and add ssop-=buffers to your vimrc.


xolox/vim-session is working well for me. With Vundle:

Plugin 'xolox/vim-misc'
Plugin 'xolox/vim-session'
let g:session_autoload = 'yes'
let g:session_autosave = 'yes'
let g:session_autosave_to = 'default'
let g:session_verbose_messages = 0

Session is stored in ~/.vim/sessions/default.vim.


The autosess plugin works well for this. Also available on GitHub: powerman/vim-plugin-autosess.

From the plugin's description:

Start Vim without file arguments to automatically load previous session for current directory. This make easier work with complex projects - just chdir to project directory and start vim.

When you quit from Vim, if there are more than one open tab/window, session will be automatically saved. This let you edit single files in same directory without breaking your saved session. (Quickfix and vimdiff's windows are ignored.)

If you quit from Vim with no open files, session will be deleted. This let you start usual empty Vim in this directory next time.


i use vim for projects and every project have .vim folder in root of my project. and i use startup script for vim

    #!/bin/bash
if [[ $# != 1 ]]
then
    zenity --title "Vim IDE usage error" --error --text "Usage: vim_ide /path/to/project/dir."
    exit 1
fi

if [[ ! -e "$1/.vim/ide.vim" ]]
then
    zenity --title "Vim IDE usage error" --error --text "'$1' is not a Vim IDE project directory."
    exit 1
fi

cd "$1" || { zenity --title "Vim IDE usage error" --error --text "Can't change current directory to Vim IDE project directory '$1'."; exit 1; }

.vim/ide.vim

set sessionoptions-=options
au VimLeave * :mksession! .vim/ide.session
    if getfsize(".vim/ide.session") >= 0
        source .vim/ide.session
    endif

so i start my vim by next command

$~/ide.sh /path/to/project

All my opened files, tabs and even position cursors are saved before exit and restored after start.


With gsessions you still have to save your sessions with \ss before quitting the editor. It will detect saved sessions on startup, and ask you if you want to open them.


I have a muscle-memory habit of typing ":q!", which I haven't been able to shake. This gets very tedious, if I've got multiple buffers open in a vi session. So - what I needed was a way of simply recovering where I was when I accidentally shot myself in the foot. Again.

This is slightly complicated by the fact that I might have multiple ssh sessions open at any one time, each with a different set of buffers/windows open in vi. I needed a way of saving the session separately for each different ssh session.

The solution I came up with builds on 2ck's answer, and is as follows. In your ~/.vimrc:

" tty is unique to the ssh session
let my_full_tty=$SSH_TTY
" scoop the number off the end of it
let my_tty_num = matchstr(my_full_tty, '\d\{1,}$')
" create a unique filename
let g:my_vim_session = "~/vim_session." . my_tty_num

fu! SaveSess()
    execute 'mksession! ' . g:my_vim_session
endfunction

fu! RestoreSess()
    let file = expand(g:my_vim_session)
    if filereadable(file)
        execute 'source ' . g:my_vim_session
    endif
endfunction

autocmd VimLeave * call SaveSess()
" only restore the session if the user has -not- requested a specific filename
autocmd VimEnter * if !argc() | call RestoreSess() | endif

But, of course, I don't want loads of ~/vim_session.? lying around, so I periodically cleanup. (I may re-think this, actually, because what happens if my ssh disconnects unexpectedly? hmmm)

In your .bashrc:

trap ~/bash_exit_script.pl EXIT

and in bash_exit_script.pl:

#! /usr/bin/perl

use warnings;
use strict;

my $ssh_tty = $ENV{SSH_TTY};
$ssh_tty =~ /(\d{1,}$)/; 
my $my_tty_number = $1;

my $filename = "/home/dominic.pain/vim_session.$my_tty_number";
if(-e $filename) {
    print "tried to remove $filename...\n";
    system("rm $filename");
}      
else {
    print "Couldn't find $filename\n";
}


tpope's vim-obsession is the best thing for this now, released after the question was originally asked.

Use :Obsess (with optional file/directory name) to start recording to a session file and :Obsess! to stop and throw it away. That's it. Load a session in the usual manner: vim -S, or :source it.

  • Instead of making me remember to capture the session immediately before exiting Vim, allow me to do it at any time, and automatically re-invoke :mksession immediately before exit.
  • Also invoke :mksession whenever the layout changes (in particular, on BufEnter), so that even if Vim exits abnormally, I'm good to go.
  • If I load an existing session, automatically keep it updated as above.
  • If I try to create a new session on top of an existing session, don't refuse to overwrite it. Just do what I mean.


Improving on @Wolph here is a more robust code that treats each session for each file separatly:

" vim auto-save session
fu! SaveSess()
    execute 'mksession! ' . getcwd() . '/.' . expand('%:t') . '.vim'
endfunction

fu! RestoreSess()
if filereadable(getcwd() . '/.' . expand('%:t') . '.vim')
    execute 'so ' . getcwd() . '/.' . expand('%:t') . '.vim'
    if bufexists(1)
        for l in range(1, bufnr('$'))
            if bufwinnr(l) == -1
                exec 'sbuffer ' . l
            endif
        endfor
    endif
endif
endfunction

autocmd VimLeavePre * call SaveSess()
autocmd VimEnter * nested call RestoreSess()

Put this code on .vimrc


You can add the following line to your .vimrc file to automatically save the session when you quit Vim with :qa:

au VimLeave * mksession! .session.vim

Then to automatically load it, add this:

autocmd VimEnter * source .session.vim
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜