Vim 7.4 won't let us quit windows from a script.
[profile.git] / .vim / plugin / clipbrd.vim
1 " clipbrd.vim -- Clipboard and other register content editor.
2 " Author: Hari Krishna (hari_vim at yahoo dot com)
3 " Last Change: 01-Jun-2006 @ 17:57
4 " Created: 26-May-2004
5 " Requires: Vim-7.0, genutils.vim(2.0)
6 " Version: 2.0.1
7 " Licence: This program is free software; you can redistribute it and/or
8 "          modify it under the terms of the GNU General Public License.
9 "          See http://www.gnu.org/copyleft/gpl.txt 
10 " Download From:
11 "     http://www.vim.org/script.php?script_id=1014
12 " Usage:
13 "   - Execute the default map (\cb or <Leader>cb) or :ClipBrd command to view
14 "     the default register ("*", the clipboard register). You can also specify
15 "     the register name as an argument to the :ClipBrd command.
16 "   - The register name is remembered (until you change it again by explicitly
17 "     specifying it) so that you don't have to specify it everytime you run
18 "     :ClipBrd command.
19 "   - The "[Clip Board]" buffer is like a regular Vim file buffer, as you can
20 "     write (:w, :w!, :wq, :wq!), reload (:e, :e!) and quit (:q, :q!) the
21 "     buffer using the built-in Vim commands. Writing without the bang will
22 "     make the plugin prompt you for confirmation and where available, you can
23 "     click "Cancel" to prevent the buffer from quitting.
24 "   - To refresh contents from the register, use :e or :e! command, or just
25 "     close and reopen the buffer. To quit without saving, just use the :q!
26 "     command.
27 "   - <C-G> while in the [Clip Board] buffer shows the register name.
28 "   - Even other buffer commands and settings work as expected, e.g., you can
29 "     :hide the buffer if you can't decide to save or quit, and the contents
30 "     should remain the same when you come back, unless a different register
31 "     is explicitly specified while opening the clipboard. Setting 'bufhidden'
32 "     to "hide" or 'hidden' also should do the same.
33 " Installation:
34 "   - Place the file in your plugin directory.
35 "   - Also install the latest genutils.vim.
36 "   - If you don't like the default map (\cb), change it by placing the
37 "     following in your vimrc (change <Your Map> appropriately):
38 "       nmap <unique> <silent> <Your Map> <Plug>ClipBrdOpen
39 "   - If you want to change the default register from "*" to something else,
40 "     put the following in your vimrc:
41 "       let g:clipbrdDefaultReg = '+' 
42 "     The default register is significant only the first time you invoke the
43 "     ClipBrd without specifying any register.  
44 "   - You can optionally create a program shortcut with the following as the
45 "     command:
46 "
47 "       gvim +ClipBrd +only
48 "
49 "     This allows you to use the shortcut to quickly view and edit the
50 "     system clipboard. I find it extremely useful. Place the shortcut in a
51 "     quick reach (like the windows taskbar) and you will have a powerful
52 "     clipboard editor handy all the time.
53 " TODO:
54
55 if exists('loaded_clipbrd')
56   finish
57 endif
58 if v:version < 700
59   "echomsg 'clipbrd: You need at least Vim 7.0'
60   finish
61 endif
62
63 if !exists('loaded_genutils')
64   runtime plugin/genutils.vim
65 endif
66 if !exists('loaded_genutils') || loaded_genutils < 200
67   echomsg 'clipbrd: You need a newer version of genutils.vim plugin'
68   finish
69 endif
70 let loaded_clipbrd=1
71
72 if !exists('s:myBufNum')
73 let s:myBufNum = -1
74 let s:myDir = ''
75 if exists('g:clipbrdDefaultReg')
76   let s:curReg = g:clipbrdDefaultReg
77 else
78   let s:curReg = '*'
79 endif
80 let s:title = '[Clip Board]'
81 endif
82
83 command! -nargs=? ClipBrd :call <SID>ViewRegister(<f-args>)
84
85 if (! exists("no_plugin_maps") || ! no_plugin_maps) &&
86       \ (! exists("no_clipbrd_maps") || ! no_clipbrd_maps)
87   nnoremap <script> <Plug>ClipBrdOpen :ClipBrd<CR>
88
89   if !hasmapto('<Plug>ClipBrdOpen')
90     nmap <unique> <silent> <Leader>cb <Plug>ClipBrdOpen
91   endi
92 endif
93
94 function! s:ViewRegister(...)
95   let forceRefresh = 0
96   if (a:0 > 0 && a:1 != s:curReg)
97     let s:curReg = (a:0 > 0 ? a:1 : s:curReg)
98     let forceRefresh = 1
99   endif
100
101   if s:myBufNum == -1
102     " Temporarily modify isfname to avoid treating the name as a pattern.
103     let _isf = &isfname
104     try
105       set isfname-=\
106       set isfname-=[
107       if exists('+shellslash')
108         exec "sp \\\\". escape(s:title, ' ')
109       else
110         exec "sp \\". escape(s:title, ' ')
111       endif
112       exec "normal i\<C-G>u\<Esc>"
113       let s:myBufNum = bufnr('%')
114       let s:myDir = getcwd()
115     finally
116       let &isfname = _isf
117     endtry
118   else
119     let buffer_win = bufwinnr(s:myBufNum)
120     if buffer_win == -1
121       exec 'sb '. s:myBufNum
122       if a:0 == 0
123         return | " BufReadCmd must have done the trick.
124       endif
125     elseif buffer_win != winnr()
126       exec buffer_win . 'wincmd w'
127     endif
128     " Preserve the buffername, in case the user changed the directory. This is
129     "   a hack to get the same functionality as buftype=nofile itself, without
130     "   needing to set it (since we want 'modified' flag to be working).
131     if s:myDir !=# getcwd()
132       try
133         exec 'lcd' s:myDir
134         setl buftype=nofile
135         lcd -
136         setl buftype=
137       catch
138         " Ignore.
139       endtry
140     endif
141   endif
142   call s:SetupBuf(s:curReg)
143
144   if forceRefresh || (line('$') == 1 && getline(1) =~ '^$')
145     call genutils#OptClearBuffer()
146     let v:errmsg = ''
147     silent! exec '$put '.s:curReg
148     if v:errmsg != ''
149       echohl ErrorMsg | echo v:errmsg | echohl NONE
150       return
151     endif
152     silent 1delete _
153     setlocal nomodified
154   endif
155 endfunction
156
157 function! s:UpdateRegister(confirmed, cancellable)
158   if a:confirmed || v:cmdbang
159     let response = 1
160   else
161     let response = confirm('Do you want to update register: "'.s:curReg.
162           \ '"? ', "&Yes\n&No".(a:cancellable?"\n&Cancel":''), 1, 'Question')
163   endif
164   if response == 1
165     silent exec '1,$yank' s:curReg
166   endif
167   if response != 3 " If not cancelled.
168     setl nomodified
169   else
170     setl modified
171   endif
172 endfunction
173
174 function! s:SetupBuf(regName)
175   call genutils#SetupScratchBuffer()
176   " We are not setting 'buftype' as this will make BufWriteCmd unusable.
177   setlocal buftype=
178   " We are not setting 'bufhidden' because that will allow us to :hide it,
179   "   without disturbing the changes.
180   setlocal bufhidden=
181
182   " Set some options suitable for pure text editing.
183   setlocal tabstop=8
184   setlocal softtabstop=0
185   setlocal shiftwidth=8
186   setlocal noexpandtab
187   setlocal autoindent
188   setlocal formatoptions=tcqnl
189   setlocal comments=:#,fb:-
190   setlocal wrapmargin=0
191   setlocal textwidth=80
192   let b:undo_ftplugin = 'setl ts< sts< sw< et< ai< fo< com< wm< tw<'
193
194   nnoremap <buffer> <silent> <C-G> :call <SID>ShowSummary()<CR>
195
196   let auTitle = escape(s:title, '\[*^$. ')
197   aug ClipBrd
198     au!
199     exec 'au BufWriteCmd ' . auTitle .' :call <SID>UpdateRegister(0, 1)'
200     exec 'au BufReadCmd ' . auTitle .' :call <SID>ViewRegister()'
201   aug END
202 endfunction
203
204 function! s:ShowSummary()
205   let summary = genutils#GetVimCmdOutput('file')
206   let summary = substitute(summary, '" \(\[New file]\)\=',
207         \ '" [Register '.s:curReg.']', '')
208   echo summary
209 endfunction
210
211 " vim6:fdm=marker et sw=2