Instant context switching using git and vim sessions.
Vim script
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
autoload/promiscuous
plugin
LICENSE
README.md

README.md

Sean Huber vim-promiscuous

Instant context switching using git and vim sessions.

What does it do?

It basically takes a snapshot of the following:

  • All of your vim tabs, buffers, splits, and folds along with their sizes and positions
  • The location of your cursor for each buffer
  • The actively selected tab/buffer
  • Your undo history (each branch's undo history is saved separately)
  • Your git stage with all tracked/untracked files and staged/unstaged hunks

When you switch to different branches using :Promiscuous your-branch-name, it takes a snapshot of the current branch and working directory, then checks out the new branch, and loads its corresponding snapshot if one exists.

If no snapshot exists, you are presented with a "fresh" vim instance that only has one tab and an empty buffer.

When :Promiscuous is called with no arguments, an :FZF fuzzy finder window is presented with a list of existing branches. From there we can either select an existing branch, or type out a new branch to checkout.

If you're using tmux then your status line will automatically refresh when :Promiscuous checks out a branch. This is very convenient when you display git information in your status line.

Similar projects:

Installation

Load shuber/vim-promiscuous using your favorite plugin manager e.g. Vundle

It currently depends on :FZF, but this dependency will be optional in the future.

Usage

:Promiscuous [branch]

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>

Configuration

These are the defaults. Feel free to override them.

" The directory to store all sessions and undo history
let g:promiscuous_dir = $HOME . '/.vim/promiscuous'

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

" 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 = 'promiscuous#session#save'

" Log all executed commands with echom
let g:promiscuous_verbose = 0
set sessionoptions=blank,buffers,curdir,folds,help,tabpages,winsize
set undolevels=1000
set undoreload=10000

How does it work?

call promiscuous#helpers#clear()
call promiscuous#git#stash()
call promiscuous#git#commit()

let l:branch_was = promiscuous#git#branch()
call call(g:promiscuous_save, [l:branch_was], {})

call promiscuous#session#clean()
call promiscuous#git#checkout(l:branch)

let l:branch = promiscuous#git#branch()
call call(g:promiscuous_load, [l:branch], {})

call promiscuous#git#commit_pop()
call promiscuous#git#stash_pop()
call promiscuous#tmux#refresh()

The output below occurred when switching from master to something-new then back to master.

[Promiscuous] !clear
[Promiscuous] !(git diff --quiet && git diff --cached --quiet) || (git stash save Code_vim_promiscuous_master && git stash apply)
[Promiscuous] !git add . && git commit -am '[Promiscuous]'
[Promiscuous] mksession! /Users/Sean/.vim/promiscuous/Code_vim_promiscuous_master.vim
[Promiscuous] bufdo bd
[Promiscuous] !git checkout - || git checkout -b -
[Promiscuous] source /Users/Sean/.vim/promiscuous/Code_vim_promiscuous_something_new.vim
[Promiscuous] Checkout something-new

[Promiscuous] !clear
[Promiscuous] !(git diff --quiet && git diff --cached --quiet) || (git stash save Code_vim_promiscuous_something_new && git stash apply)
[Promiscuous] !git add . && git commit -am '[Promiscuous]'
[Promiscuous] mksession! /Users/Sean/.vim/promiscuous/Code_vim_promiscuous_something_new.vim
[Promiscuous] bufdo bd
[Promiscuous] !git checkout - || git checkout -b -
[Promiscuous] source /Users/Sean/.vim/promiscuous/Code_vim_promiscuous_master.vim
[Promiscuous] Checkout master

Contributing

  • Fork the project.
  • Make your feature addition or bug fix.
  • Commit, do not mess with the version or history.
  • Send me a pull request. Bonus points for topic branches.

License

MIT - Copyright © 2015 Sean Huber