├── .gitignore ├── README.md ├── autoload └── WindowSwap.vim ├── doc └── windowswap.txt └── plugin └── WindowSwap.vim /.gitignore: -------------------------------------------------------------------------------- 1 | docs/tags 2 | doc/tags 3 | *~ 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | WindowSwap.vim 2 | ============== 3 | Swap windows without ruining your layout! 4 | 5 | ![img](http://i.imgur.com/jo3V05S.gif) 6 | 7 | Vim's window movement commands work fine when you only have a few splits open or want to push a window over to an edge. But what happens when you have a complicated layout and you just want to swap a couple arbitrary windows? 8 | 9 | When I was just getting started with Vim, [I asked about this problem on StackOverflow][1] and I've received a handful of responses over the years. Almost a year after after I asked, [sgriffin came through with a solution][2]. Now that I'm a little less of a newbie, I've put his idea in a handy plugin. 10 | 11 | HowTo 12 | --------------- 13 | 1. Navigate to the window you'd like to move 14 | 2. Press `ww` 15 | 3. Navigate to the window you'd like to swap with 16 | 4. Press `ww` again 17 | 18 | Key Bindings 19 | ---------------- 20 | Defaults: 21 | * Yank and paste a window with `ww` (for me that's `,ww`) 22 | 23 | **Deprecated** defaults: 24 | * [y]ank a [w]indow with `yw` 25 | * [p]aste that [w]indow with `pw`. 26 | 27 | These mappings are deprecated. See below for instructions on how to keep them working once they are removed from the default list. 28 | 29 | Customize the commands to your liking by dropping this in your `.vimrc` and changing the mappings: 30 | 31 | ```VimL 32 | let g:windowswap_map_keys = 0 "prevent default bindings 33 | nnoremap yw :call WindowSwap#MarkWindowSwap() 34 | nnoremap pw :call WindowSwap#DoWindowSwap() 35 | nnoremap ww :call WindowSwap#EasyWindowSwap() 36 | ``` 37 | Installation 38 | ------------ 39 | 40 | This plugin follows the standard runtime path structure, and as such it can be installed with a variety of plugin managers: 41 | * [Vundle][13] - `Plugin 'wesQ3/vim-windowswap'` 42 | * [Pathogen][11] - `git clone https://github.com/wesQ3/vim-windowswap ~/.vim/bundle/vim-windowswap` 43 | * [NeoBundle][12] - `NeoBundle 'wesQ3/vim-windowswap'` 44 | * [VAM][22] - `call vam#ActivateAddons([ 'wesQ3/vim-windowswap' ])` 45 | * manual - copy all of the files into your `~/.vim` directory 46 | 47 | [1]: http://stackoverflow.com/q/2586984/77782 48 | [2]: http://stackoverflow.com/a/4903681/77782 49 | [11]: https://github.com/tpope/vim-pathogen 50 | [12]: https://github.com/Shougo/neobundle.vim 51 | [13]: https://github.com/gmarik/vundle 52 | [22]: https://github.com/MarcWeber/vim-addon-manager 53 | -------------------------------------------------------------------------------- /autoload/WindowSwap.vim: -------------------------------------------------------------------------------- 1 | " WindowSwap! 2 | 3 | let s:markedWinNum = [] 4 | 5 | function! WindowSwap#MarkWindowSwap() 6 | call WindowSwap#SetMarkedWindowNum( tabpagenr(), winnr() ) 7 | endfunction 8 | 9 | function! WindowSwap#DoWindowSwap() 10 | if !WindowSwap#HasMarkedWindow() 11 | echom "WindowSwap: No window marked to swap! Mark a window first." 12 | return 13 | endif 14 | "Mark destination 15 | let curTab = tabpagenr() 16 | let curNum = winnr() 17 | let curView = winsaveview() 18 | let curBuf = bufnr( "%" ) 19 | let targetWindow = WindowSwap#GetMarkedWindowTuple() 20 | exe "tabn " . targetWindow[0] 21 | exe targetWindow[1] . "wincmd w" 22 | "Switch to source and shuffle dest->source 23 | let markedView = winsaveview() 24 | let markedBuf = bufnr( "%" ) 25 | "Hide and open so that we aren't prompted and keep history 26 | exe 'hide buf ' . curBuf 27 | call winrestview(curView) 28 | "Switch to dest and shuffle source->dest 29 | exe "tabn " . curTab 30 | exe curNum . "wincmd w" 31 | "Hide and open so that we aren't prompted and keep history 32 | exe 'hide buf ' . markedBuf 33 | call winrestview(markedView) 34 | call WindowSwap#ClearMarkedWindowNum() 35 | endfunction 36 | 37 | function! WindowSwap#EasyWindowSwap() 38 | if WindowSwap#HasMarkedWindow() 39 | call WindowSwap#DoWindowSwap() 40 | else 41 | call WindowSwap#MarkWindowSwap() 42 | endif 43 | endfunction 44 | 45 | " Deprecated: Only returns the window number for back compat 46 | function! WindowSwap#GetMarkedWindowNum() 47 | if s:markedWinNum == [] 48 | return 0 49 | else 50 | return s:markedWinNum[1] 51 | endif 52 | endfunction 53 | 54 | function! WindowSwap#GetMarkedWindowTuple() 55 | return s:markedWinNum 56 | endfunction 57 | 58 | function! WindowSwap#SetMarkedWindowNum(tab,win) 59 | let s:markedWinNum = [a:tab,a:win] 60 | endfunction 61 | 62 | function! WindowSwap#ClearMarkedWindowNum() 63 | let s:markedWinNum = [] 64 | endfunction 65 | 66 | function! WindowSwap#HasMarkedWindow() 67 | if s:markedWinNum == [] 68 | return 0 69 | else 70 | return 1 71 | endif 72 | endfunction 73 | 74 | function! WindowSwap#IsCurrentWindowMarked() 75 | return WindowSwap#IsWindowMarked(tabpagenr(),winnr()) 76 | endfunction 77 | 78 | function! WindowSwap#IsWindowMarked(tab,win) 79 | if WindowSwap#HasMarkedWindow() && s:markedWinNum[0] == a:tab && s:markedWinNum[1] == a:win 80 | return 1 81 | else 82 | return 0 83 | endif 84 | endfunction 85 | 86 | function! WindowSwap#DeprecationNotice() 87 | if g:windowswap_mapping_deprecation_notice 88 | echom "This default mapping is deprecated and will be removed in the future. Please see :help windowswap-functions." 89 | return 90 | endif 91 | endfunction 92 | 93 | function! WindowSwap#DeprecatedMark() 94 | call WindowSwap#DeprecationNotice() 95 | call WindowSwap#MarkWindowSwap() 96 | endfunction 97 | 98 | function! WindowSwap#DeprecatedDo() 99 | call WindowSwap#DeprecationNotice() 100 | call WindowSwap#DoWindowSwap() 101 | endfunction 102 | -------------------------------------------------------------------------------- /doc/windowswap.txt: -------------------------------------------------------------------------------- 1 | *windowswap.txt* For Vim version 7.3 *windowswap* 2 | 3 | WINDOWSWAP MANUAL 4 | 5 | 1. About WindowSwap |windowswap-about| 6 | 2. Quick Start |windowswap-quickstart| 7 | 3. Key Mappings and Functions |windowswap-keymappings| 8 | |windowswap-functions| 9 | 4. Options |windowswap-options| 10 | 11 | ============================================================================= 12 | 1. ABOUT WINDOWSWAP ~ 13 | *windowswap-about* 14 | 15 | WindowSwap helps you swap your buffers between existing split windows without 16 | affecting your current split layout. 17 | 18 | Vim's window movement commands work fine when you only have a few splits open 19 | or want to push a window over to an edge. But what happens when you have a 20 | complicated layout and you just want to swap a couple arbitrary windows? That 21 | is where WindowSwap can help out. 22 | 23 | My thanks to `sgriffin` on stackoverflow.com who helped me out when I was just 24 | a vim newbie in need of some window-shuffle incantations. His anwser formed 25 | the core of WindowSwap (and remains so, currently). Give the man your upvote, 26 | folks. The SO question where this little plugin started is here: 27 | 28 | http://stackoverflow.com/q/2586984/77782 29 | 30 | ============================================================================= 31 | 2. QUICK START ~ 32 | *windowswap-quickstart* 33 | 34 | If all you need to do is swap some windows around, usage is pretty simple: 35 | 36 | 1. Navigate to the window you'd like to move 37 | 2. Press `ww` to mark that window for a future swap 38 | 3. Navigate to the window you'd like to swap with 39 | 4. Press `ww` again to swap the marked window with the current one 40 | 41 | That's it! 42 | 43 | ============================================================================= 44 | 3. KEY MAPPINGS AND FUNCTIONS ~ 45 | *windowswap-keymappings* *windowswap-functions* 46 | 47 | First of all, you can prevent these default bindings by setting 48 | `g:windowswap_map_keys` to `0` in your `.vimrc`. 49 | 50 | *WindowSwap#EasyWindowSwap* `ww` 51 | Mark current window if none is marked, swap current window with marked window 52 | if mark is currently set. Clears marked window flag after swapping. 53 | 54 | *WindowSwap#IsWindowMarked* `none` 55 | Args: (`tabnum`, `winnum`) 56 | Returns true if the window located at tab number `tabnum` and window number 57 | `winnum` is currently marked for swapping. Returns false otherwise. 58 | 59 | *WindowSwap#IsCurrentWindowMarked* `none` 60 | Returns true if the currently selected window is marked for swapping. Returns 61 | false otherwise. 62 | 63 | *WindowSwap#MarkWindowSwap* `yw` 64 | Mark current window to be swapped. If the mark is already set to another 65 | window, update the mark to the new window. 66 | Note: This default mapping is deprecated. You'll have to put it in your .vimrc 67 | yourself if you want it to keep working in the future: 68 | > 69 | nnoremap yw :call WindowSwap#MarkWindowSwap() 70 | < 71 | 72 | *WindowSwap#DoWindowSwap* `pw` 73 | Swap marked window with currently active window. If no mark is set, the user 74 | is chastised accordingly. 75 | Note: This default mapping is deprecated. You'll have to put it in your .vimrc 76 | yourself if you want it to keep working in the future: 77 | > 78 | nnoremap pw :call WindowSwap#DoWindowSwap() 79 | < 80 | 81 | ============================================================================= 82 | 4. OPTIONS ~ 83 | *windowswap-options* 84 | 85 | *g:windowswap_map_keys* default: `1` 86 | Allow WindowSwap to map its default keys. Set to `0` to prevent any key 87 | mappings. 88 | 89 | *g:windowswap_mapping_deprecation_notice* default: `1` 90 | Allow deprecation notices upon using deprecated default bindings. 91 | 92 | vim: set expandtab sts=2 ts=2 sw=2 tw=78 ft=help norl: 93 | -------------------------------------------------------------------------------- /plugin/WindowSwap.vim: -------------------------------------------------------------------------------- 1 | if !exists('g:windowswap_map_keys') 2 | let g:windowswap_map_keys = 1 3 | endif 4 | 5 | if !exists('g:windowswap_mapping_deprecation_notice') 6 | let g:windowswap_mapping_deprecation_notice = 1 7 | endif 8 | 9 | if g:windowswap_map_keys 10 | nnoremap ww :call WindowSwap#EasyWindowSwap() 11 | nnoremap yw :call WindowSwap#DeprecatedMark() 12 | nnoremap pw :call WindowSwap#DeprecatedDo() 13 | endif 14 | 15 | let g:loaded_windowswap = 1 16 | --------------------------------------------------------------------------------