Fix missing slashes in short dir.
[profile.git] / .vim / autoload / nrrwrgn.vim
1 " nrrwrgn.vim - Narrow Region plugin for Vim
2 " -------------------------------------------------------------
3 " Version:         0.31
4 " Maintainer:  Christian Brabandt <cb@256bit.org>
5 " Last Change: Sat, 16 Feb 2013 22:28:31 +0100
6 "
7 " Script: http://www.vim.org/scripts/script.php?script_id=3075 
8 " Copyright:   (c) 2009, 2010, 2011, 2012, 2013 by Christian Brabandt
9 "                          The VIM LICENSE applies to NrrwRgn.vim 
10 "                          (see |copyright|) except use "NrrwRgn.vim" 
11 "                          instead of "Vim".
12 "                          No warranty, express or implied.
13 "        *** ***   Use At-Your-Own-Risk!   *** ***
14 " GetLatestVimScripts: 3075 31 :AutoInstall: NrrwRgn.vim
15 "
16 " Functions:
17
18 fun! <sid>WarningMsg(msg) "{{{1
19         let msg = "NarrowRegion: ". a:msg
20         echohl WarningMsg
21         if exists(":unsilent") == 2
22                 unsilent echomsg msg
23         else
24                 echomsg msg
25         endif
26         sleep 1
27         echohl Normal
28         let v:errmsg = msg
29 endfun
30
31 fun! <sid>Init() "{{{1
32         if !exists("s:opts")
33                 " init once
34                 let s:opts = []
35         endif
36         if !exists("s:instn")
37                 let s:instn=1
38                 if !exists("g:nrrw_custom_options") || empty(g:nrrw_custom_options)
39                         let s:opts=<sid>Options('local to buffer')
40         endif
41         else
42                 " Prevent accidently overwriting windows with instn_id set
43                 " back to an already existing instn_id
44                 let s:instn = (s:instn==0 ? 1 : s:instn)
45                 while (has_key(s:nrrw_rgn_lines, s:instn))
46                         let s:instn+=1
47                 endw
48         endif
49         let s:nrrw_aucmd = {}
50         if exists("b:nrrw_aucmd_create")
51                 let s:nrrw_aucmd["create"] = b:nrrw_aucmd_create
52         endif
53         if exists("b:nrrw_aucmd_close")
54                 let s:nrrw_aucmd["close"] = b:nrrw_aucmd_close
55         endif
56         if !exists("s:nrrw_rgn_lines")
57                 let s:nrrw_rgn_lines = {}
58         endif
59         let s:nrrw_rgn_lines[s:instn] = {}
60         " show some debugging messages
61         let s:nrrw_winname='Narrow_Region'
62
63         " Customization
64         let s:nrrw_rgn_vert = (exists("g:nrrw_rgn_vert") ? g:nrrw_rgn_vert : 0)
65         let s:nrrw_rgn_wdth = (exists("g:nrrw_rgn_wdth") ? g:nrrw_rgn_wdth : 20)
66         let s:nrrw_rgn_hl       = (exists("g:nrrw_rgn_hl")       ? g:nrrw_rgn_hl   :
67                                                         \ "WildMenu")
68         let s:nrrw_rgn_nohl = (exists("g:nrrw_rgn_nohl") ? g:nrrw_rgn_nohl : 0)
69
70         let s:debug         = (exists("s:debug") ? s:debug : 0)
71                 
72 endfun 
73
74 fun! <sid>NrrwRgnWin(bang) "{{{1
75         let local_options = <sid>GetOptions(s:opts)
76         let nrrw_winname = s:nrrw_winname. '_'. s:instn
77         let nrrw_win = bufwinnr('^'.nrrw_winname.'$')
78         if nrrw_win != -1
79                 exe ":noa ". nrrw_win. 'wincmd w'
80                 " just in case, a global nomodifiable was set 
81                 " disable this for the narrowed window
82                 setl ma
83                 silent %d _
84         else
85                 if !exists('g:nrrw_topbot_leftright')
86                         let g:nrrw_topbot_leftright = 'topleft'
87                 endif
88                 if !a:bang
89                         exe  g:nrrw_topbot_leftright s:nrrw_rgn_wdth.
90                                 \(s:nrrw_rgn_vert?'v':''). "sp ". nrrw_winname
91                 else
92                         try 
93                                 " if hidden is set, set the original buffer to be modified, so
94                                 " that :q won't accidently quit vim
95                                 if &hid
96                                         setl modified
97                                 endif
98                                 enew
99                                 if bufexists(s:nrrw_winname. '_'. s:instn)
100                                         " avoid E95
101                                         exe 'bw' s:nrrw_winname. '_'. s:instn
102                                 endif
103                                 exe 'f' s:nrrw_winname. '_'. s:instn
104                         catch /^Vim\%((\a\+)\)\=:E37/   " catch error E37
105                                 " Fall back and use a new window
106                                 exe  g:nrrw_topbot_leftright s:nrrw_rgn_wdth.
107                                         \(s:nrrw_rgn_vert?'v':''). "sp ". nrrw_winname
108                         endtry
109                 endif
110
111                 " just in case, a global nomodifiable was set 
112                 " disable this for the narrowed window
113                 setl ma
114                 " Just in case
115                 silent %d _
116                 " Set up some options like 'bufhidden', 'noswapfile', 
117                 " 'buftype', 'bufhidden', when enabling Narrowing.
118                 call <sid>NrrwSettings(1)
119                 let nrrw_win = bufwinnr("")
120         endif
121         call <sid>SetOptions(local_options)
122         " We are in the narrowed buffer now!
123         return nrrw_win
124 endfun
125
126 fun! <sid>CleanRegions() "{{{1
127          let s:nrrw_rgn_line=[]
128          unlet! s:nrrw_rgn_last
129          unlet! s:nrrw_rgn_buf
130 endfun
131
132 fun! <sid>CompareNumbers(a1,a2) "{{{1
133         return (a:a1+0) == (a:a2+0) ? 0
134                 \ : (a:a1+0) > (a:a2+0) ? 1
135                 \ : -1
136 endfun
137
138 fun! <sid>ParseList(list) "{{{1
139          " for a given list of line numbers, return those line numbers
140          " in a format start:end for continous items, else [start, next]
141      let result={}
142      let start=0
143      let temp=0
144      let i=1
145      for item in sort(a:list, "<sid>CompareNumbers")
146          if start==0
147             let start=item
148                  elseif temp!=item-1
149              let result[i]=[start,temp]
150              let start=item
151                          let i+=1
152          endif
153                  let temp=item
154      endfor
155          if empty(result)
156                  " add all items from the list to the result
157                  " list consists only of consecutive items
158                  let result[i] = [a:list[0], a:list[-1]]
159          endif
160          " Make sure the last item is included in the selection
161          if get(result, (i-1), 0)[0] && result[i-1][1] != item
162                  let result[i]=[start,item]
163          endif
164      return result
165 endfun
166
167 fun! <sid>WriteNrrwRgn(...) "{{{1
168         " if argument is given, write narrowed buffer back
169         " else destroy the narrowed window
170         let nrrw_instn = exists("b:nrrw_instn") ? b:nrrw_instn : s:instn
171         if exists("b:orig_buf") && (bufwinnr(b:orig_buf) == -1) &&
172                 \ !<sid>BufInTab(b:orig_buf) &&
173                 \ !bufexists(b:orig_buf)
174                 call s:WarningMsg("Original buffer does no longer exist! Aborting!")
175                 return
176         endif
177         if &l:mod && exists("a:1") && a:1
178                 " Write the buffer back to the original buffer
179                 setl nomod
180                 exe ":WidenRegion"
181                 if bufname('') !~# 'Narrow_Region' && bufwinnr(s:nrrw_winname. '_'. s:instn) > 0
182                         exe ':noa'. bufwinnr(s:nrrw_winname. '_'. s:instn). 'wincmd w'
183                 endif
184         else
185                 call <sid>StoreLastNrrwRgn(nrrw_instn)
186                 let winnr = bufwinnr(b:orig_buf)
187                 " Best guess
188                 if bufname('') =~# 'Narrow_Region' && winnr > 0
189                         exe ':noa'. winnr. 'wincmd w'
190                 endif
191                 if !exists("a:1") 
192                         " close narrowed buffer
193                         call <sid>NrrwRgnAuCmd(nrrw_instn)
194                 endif
195         endif
196 endfun
197
198 fun! <sid>SaveRestoreRegister(values) "{{{1
199         if empty(a:values)
200                 " Save
201                 let reg        = ['a', getreg('a'), getregtype('a') ]
202                 let fold =  [ &fen, &l:fdm ]
203                 if &fen
204                         setl nofoldenable
205                 endif
206                 let visual = [getpos("'<"), getpos("'>")]
207                 return  [ reg, fold, visual ]
208         else
209                 " Restore
210                 if empty(a:values)
211                         call <sid>WarningMsg("Error setting options back!")
212                         return
213                 endif
214                 call call('setreg', a:values[0])
215                 if a:values[1][0]
216                         setl foldenable
217                         let &l:fdm=a:values[1][1]
218                 endif
219                 if v:version > 703 || (v:version == 703 && has("patch590"))
220                         " settable '< and '> marks
221                         call setpos("'<", a:values[2][0])
222                         call setpos("'>", a:values[2][1])
223                 endif
224         endif
225 endfun!
226
227 fun! <sid>NrrwRgnAuCmd(instn) "{{{1
228         " If a:instn==0, then enable auto commands
229         " else disable auto commands for a:instn
230         if !a:instn
231                 exe "aug NrrwRgn". b:nrrw_instn
232                         au!
233                         au BufWriteCmd <buffer> nested :call s:WriteNrrwRgn(1)
234                         au BufWinLeave,BufWipeout,BufDelete <buffer> nested
235                                                 \ :call s:WriteNrrwRgn()
236                 aug end
237         else
238                 exe "aug NrrwRgn".  a:instn
239                 au!
240                 aug end
241                 exe "aug! NrrwRgn". a:instn
242                 
243                 if !has_key(s:nrrw_rgn_lines, a:instn)
244                         " narrowed buffer was already cleaned up
245                         call <sid>DeleteMatches(a:instn)
246                         call s:WarningMsg("Window was already cleaned up. Nothing to do.")
247                         return
248                 endif
249
250                 " make the original buffer modifiable, if possible
251                 let buf = s:nrrw_rgn_lines[a:instn].orig_buf
252                 if !getbufvar(buf, '&l:ma') && !getbufvar(buf, 'orig_buf_ro')
253                         call setbufvar(s:nrrw_rgn_lines[a:instn].orig_buf, '&ma', 1)
254                 endif
255
256                 if s:debug
257                         echo printf("bufnr: %d a:instn: %d\n", bufnr(''), a:instn)
258                         echo "bwipe " s:nrrw_winname. '_'. a:instn
259                 endif
260                 if (has_key(s:nrrw_rgn_lines[a:instn], 'disable') &&
261                 \       !s:nrrw_rgn_lines[a:instn].disable ) ||
262                 \   !has_key(s:nrrw_rgn_lines[a:instn], 'disable')
263                         call <sid>DeleteMatches(a:instn)
264                         " bwipe! throws E855 (catching does not work)
265                         " but because of 'bufhidden' wipeing will happen anyways
266                         "exe "bwipe! " bufnr(s:nrrw_winname. '_'. a:instn)
267 "                       if has_key(s:nrrw_rgn_lines[a:instn], 'single') &&
268 "                       \  s:nrrw_rgn_lines[a:instn].single
269                                 " If there is only a single window open don't clean up now
270                                 " because we can't put the narrowed lines back, so do not
271                                 " clean up now. We need to clean up then later. But how?
272 "                               return
273 "                       endif
274                         call <sid>CleanUpInstn(a:instn)
275                 endif
276         endif
277 endfun
278
279 fun! <sid>CleanUpInstn(instn) "{{{1
280         if s:instn>=1 && has_key(s:nrrw_rgn_lines, a:instn)
281                 unlet s:nrrw_rgn_lines[a:instn]
282                 let s:instn-=1
283         endif
284 endfu
285
286 fun! <sid>StoreLastNrrwRgn(instn) "{{{1
287         " Only store the last region, when the narrowed instance is still valid
288         if !has_key(s:nrrw_rgn_lines, a:instn)
289                 call <sid>WarningMsg("Error storing the last Narrowed Window,".
290                                         \ "it's invalid!")
291                 return
292         endif
293
294         let s:nrrw_rgn_lines['last'] = []
295         if !exists("b:orig_buf")
296                 let orig_buf = s:nrrw_rgn_lines[a:instn].orig_buf
297         else
298                 let orig_buf = b:orig_buf
299         endif
300         if has_key(s:nrrw_rgn_lines[a:instn], 'multi')
301                 call add(s:nrrw_rgn_lines['last'], [ orig_buf, 
302                         \ s:nrrw_rgn_lines[a:instn]['multi']])
303         else
304                 " Linewise narrowed region, pretend it was done like a visual
305                 " narrowed region
306                 let s:nrrw_rgn_lines['last'] = [ [ orig_buf,
307                 \ s:nrrw_rgn_lines[a:instn].start[1:]], 
308                 \ [ orig_buf, s:nrrw_rgn_lines[a:instn].end[1:]]]
309                 call add(s:nrrw_rgn_lines['last'],
310                                         \ has_key(s:nrrw_rgn_lines[a:instn], 'vmode') ?
311                                         \ s:nrrw_rgn_lines[a:instn].vmode : 'V')
312         endif
313 endfu
314
315 fun! <sid>RetVisRegionPos() "{{{1
316         if v:version > 703 || (v:version == 703 && has("patch590"))
317                 return [ getpos("'<"), getpos("'>") ]
318         else
319                 return [ getpos("'<")[0:1] + [virtcol("'<"), 0],
320                         \    getpos("'>")[0:1] + [virtcol("'>"), 0] ]
321         endif
322 endfun
323
324 fun! <sid>GeneratePattern(startl, endl, mode, ...) "{{{1
325         if exists("a:1") && a:1
326                 let block = 0
327         else
328                 let block = 1
329         endif
330         " This is just a best guess, the highlighted block could still be wrong
331         " (a " rectangle has been selected, but the complete lines are
332         " highlighted
333         if a:mode ==# '\16' && a:startl[0] > 0 && a:startl[1] > 0 && block
334                 return '\%>'. (a:startl[0]-1). 'l\&\%>'. (a:startl[1]-1).
335                         \ 'v\&\%<'. (a:endl[0]+1). 'l'
336         elseif a:mode ==# '\16' && a:startl[0] > 0 && a:startl[1] > 0
337                 return '\%>'. (a:startl[0]-1). 'l\&\%>'. (a:startl[1]-1).
338                         \ 'v\&\%<'. (a:endl[0]+1). 'l\&\%<'. (a:endl[1]+1). 'v'
339         elseif a:mode ==# 'v' && a:startl[0] > 0 && a:startl[1] > 0
340                 return '\%>'. (a:startl[0]-1). 'l\&\%>'. (a:startl[1]-1).
341                         \ 'v\_.*\%<'. (a:endl[0]+1). 'l\&\%<'. (a:endl[1]+1). 'v'
342         elseif a:startl[0] > 0
343                 return '\%>'. (a:startl[0]-1). 'l\&\%<'. (a:endl[0]+1). 'l'
344         else
345                 return ''
346         endif
347 endfun 
348
349 fun! <sid>Options(search) "{{{1
350         let c=[]
351         let buf=bufnr('')
352         try
353                 " empty search pattern
354                 if empty(a:search)
355                         return c
356                 endif
357                 silent noa sview $VIMRUNTIME/doc/options.txt
358                 " for whatever reasons $VIMRUNTIME/doc/options.txt
359                 " does not exist, return empty list
360                 if line('$') == 1
361                         return c
362                 endif
363                 keepj 0
364                 let reg_a=[]
365                 call add(reg_a, 'a')
366                 call add(reg_a,getreg('a'))
367                 call add(reg_a, getregtype('a'))
368                 let @a=''
369                 exe "silent :g/". '\v'.escape(a:search, '\\/'). "/-y A"
370                 let b=split(@a, "\n")
371                 call call('setreg', reg_a)
372                 "call setreg('a', reg_a[0], reg_a[1])
373                 call filter(b, 'v:val =~ "^''"')
374                 " the following options should be set
375                 let filter_opt='\%(modifi\%(ed\|able\)\|readonly\|swapfile\|'.
376                                 \ 'buftype\|bufhidden\|foldcolumn\|buflisted\)'
377                 call filter(b, 'v:val !~ "^''".filter_opt."''"')
378                 for item in b
379                         let item=substitute(item, '''', '', 'g')
380                         call add(c, split(item, '\s\+')[0])
381                 endfor
382         finally
383                 if fnamemodify(bufname(''),':p') ==
384                    \expand("$VIMRUNTIME/doc/options.txt")
385                         bwipe
386                 endif
387                 exe "noa "      bufwinnr(buf) "wincmd  w"
388                 return c
389         endtry
390 endfun
391
392 fun! <sid>GetOptions(opt) "{{{1
393         if exists("g:nrrw_custom_options") && !empty(g:nrrw_custom_options)
394                 let result = g:nrrw_custom_options
395         else
396                 let result={}
397                 for item in a:opt
398                         try
399                                 exe "let result[item]=&l:".item
400                         catch
401                         endtry
402                 endfor
403         endif
404         return result
405 endfun
406
407 fun! <sid>SetOptions(opt) "{{{1
408          if type(a:opt) == type({})
409                 for [option, result] in items(a:opt)
410                         exe "let &l:". option " = " string(result)
411                 endfor
412          endif
413          setl nomod noro
414 endfun
415
416 fun! <sid>CheckProtected() "{{{1
417         " Protect the original window, unless the user explicitly defines not to
418         " protect it
419         if exists("g:nrrw_rgn_protect") && g:nrrw_rgn_protect =~? 'n'
420                 return
421         endif
422         let b:orig_buf_ro=0
423         if !&l:ma || &l:ro
424                 let b:orig_buf_ro=1
425                 call s:WarningMsg("Buffer is protected, won't be able to write".
426                         \ "the changes back!")
427         else 
428         " Protect the original buffer,
429         " so you won't accidentally modify those lines,
430         " that might later be overwritten
431                 setl noma
432         endif
433 endfun
434
435 fun! <sid>DeleteMatches(instn) "{{{1
436     " Make sure, we are in the correct buffer
437         " Not needed, prevents recursively narrowing
438 "       if bufname('') =~# 'Narrow_Region'
439 "               exe ':noa'. bufwinnr(b:orig_buf). 'wincmd w'
440 "       endif
441         if exists("s:nrrw_rgn_lines[a:instn].matchid")
442                 " if you call :NarrowRegion several times, without widening 
443                 " the previous region, b:matchid might already be defined so
444                 " make sure, the previous highlighting is removed.
445                 for item in s:nrrw_rgn_lines[a:instn].matchid
446                         if item > 0
447                                 " If the match has been deleted, discard the error
448                                 exe (s:debug ? "" : "silent!") "call matchdelete(item)"
449                         endif
450                 endfor
451                 let s:nrrw_rgn_lines[a:instn].matchid=[]
452         endif
453 endfun
454
455 fun! <sid>HideNrrwRgnLines() "{{{1
456         let cnc = has("Conceal")
457         let cmd='syn match NrrwRgnStart "^# Start NrrwRgn\d\+$" '.
458                                 \ (cnc ? 'conceal' : '')
459         exe cmd
460         let cmd='syn match NrrwRgnEnd "^# End NrrwRgn\d\+$" '.
461                                 \ (cnc ? 'conceal' : '')
462         exe cmd
463         syn region NrrwRgn start="^# Start NrrwRgn\z(\d\+\).*$"
464                 \ end="^# End NrrwRgn\z1$" fold transparent
465         if cnc
466                 setl conceallevel=3
467         endif
468         setl fdm=syntax
469 endfun
470
471 fun! <sid>ReturnCommentFT() "{{{1
472         " Vim
473         if &l:ft=="vim"
474                 return '"'
475         " Perl, PHP, Ruby, Python, Sh
476         elseif &l:ft=~'^\(perl\|php\|ruby\|python\|sh\)$'
477             return '#'
478         " C, C++
479         elseif &l:ft=~'^\(c\%(pp\)\?\|java\)'
480                 return '/* */'
481         " HTML, XML
482         elseif &l:ft=~'^\(ht\|x\)ml\?$'
483                 return '<!-- -->'
484         " LaTex
485         elseif &l:ft=~'^\(la\)tex'
486                 return '%'
487         else
488                 " Fallback
489                 return '#'
490         endif
491 endfun
492
493 fun! <sid>CheckRectangularRegion(reg) "{{{1
494         " Check whether the region that was pasted into
495         " register a:reg has always the same length
496         " This is needed, to be able to select the correct region
497         " when writing back the changes.
498         let result={}
499         let list=split(a:reg, "\n")
500         call map(list, 'substitute(v:val, ".", "x", "g")')
501         let llen = len(list)/2
502         call map(list, 'len(v:val)')
503         for item in list
504                 if has_key(result, item)
505                         let result[item] += 1
506                 else
507                         let result[item] = 1
508                 endif
509         endfor
510         for [key, value] in items(result)
511                 if value > llen
512                         return 1
513                 endif
514         endfor
515         return 0
516 endfu
517
518 fun! <sid>WidenRegionMulti(content, instn) "{{{1
519         " for single narrowed windows, the original narrowed buffer will be closed,
520         " so don't renew the highlighting and clean up (later in
521         " nrrwrgn#WidenRegion)
522         if empty(s:nrrw_rgn_lines[a:instn].multi)
523                 return
524         endif
525
526         let output= []
527         let list  = []
528         let [c_s, c_e] =  <sid>ReturnComments()
529         let lastline = line('$')
530         " We must put the regions back from top to bottom,
531         " otherwise, changing lines in between messes up the list of lines that
532         " still need to put back from the narrowed buffer to the original buffer
533         for key in sort(keys(s:nrrw_rgn_lines[a:instn].multi),
534                         \ "<sid>CompareNumbers")
535                 let adjust   = line('$') - lastline
536                 let range    = s:nrrw_rgn_lines[a:instn].multi[key]
537                 let last     = (len(range)==2) ? range[1] : range[0]
538                 let first    = range[0]
539                 let indexs   = index(a:content, c_s.' Start NrrwRgn'.key.c_e) + 1
540                 let indexe   = index(a:content, c_s.' End NrrwRgn'.key.c_e) - 1
541                 if indexs <= 0 || indexe < -1
542                    call s:WarningMsg("Skipping Region ". key)
543                    continue
544                 endif
545                 " Adjust line numbers. Changing the original buffer, might also 
546                 " change the regions we have remembered. So we must adjust these
547                 " numbers.
548                 " This only works, if we put the regions from top to bottom!
549                 let first += adjust
550                 let last  += adjust
551                 if last == line('$') &&  first == 1
552                         let delete_last_line=1
553                 else
554                         let delete_last_line=0
555                 endif
556                 exe ':silent :'. first. ','. last. 'd _'
557                 call append((first-1), a:content[indexs : indexe])
558                 " Recalculate the start and end positions of the narrowed window
559                 " so subsequent calls will adjust the region accordingly
560                 let  last = first + len(a:content[indexs : indexe]) - 1
561                 if last > line('$')
562                         let last = line('$')
563                 endif
564                 if !has_key(s:nrrw_rgn_lines[a:instn].multi, 'single')
565                         " original narrowed buffer is going to be closed
566                         " so don't renew the matches
567                         call <sid>AddMatches(<sid>GeneratePattern([first, 0 ],
568                                                 \ [last, 0], 'V'), a:instn)
569                 endif
570                 if delete_last_line
571                         silent! $d _
572                 endif
573         endfor
574 endfun
575         
576 fun! <sid>AddMatches(pattern, instn) "{{{1
577         if !s:nrrw_rgn_nohl || empty(a:pattern)
578                 if !exists("s:nrrw_rgn_lines[a:instn].matchid")
579                         let s:nrrw_rgn_lines[a:instn].matchid=[]
580                 endif
581                 call add(s:nrrw_rgn_lines[a:instn].matchid,
582                                         \matchadd(s:nrrw_rgn_hl, a:pattern))
583         endif
584 endfun
585
586 fun! <sid>BufInTab(bufnr) "{{{1
587         " returns tabpage of buffer a:bufnr
588         for tab in range(1,tabpagenr('$'))
589                 if !empty(filter(tabpagebuflist(tab), 'v:val == a:bufnr'))
590                         return tab
591                 endif
592         endfor
593         return 0
594 endfun
595
596 fun! <sid>JumpToBufinTab(tab,buf) "{{{1
597         if a:tab
598                 exe "noa tabn" a:tab
599         endif
600         let win = bufwinnr(a:buf)
601         if win > 0
602                 exe ':noa '. bufwinnr(a:buf). 'wincmd w'
603         endif
604 endfun
605
606 fun! <sid>RecalculateLineNumbers(instn, adjust) "{{{1
607         " This only matters, if the original window isn't protected
608         if !exists("g:nrrw_rgn_protect") || g:nrrw_rgn_protect !~# 'n'
609                 return
610         endif
611
612         for instn in filter(keys(s:nrrw_rgn_lines), 'v:val != a:instn')
613                 " Skip narrowed instances, when they are before
614                 " the region, we are currently putting back
615                 if s:nrrw_rgn_lines[instn].start[1] <=
616                 \ s:nrrw_rgn_lines[a:instn].start[1]
617                         " Skip this instn
618                         continue
619                 else 
620                    let s:nrrw_rgn_lines[instn].start[1] += a:adjust
621                    let s:nrrw_rgn_lines[instn].end[1]   += a:adjust
622
623                    if s:nrrw_rgn_lines[instn].start[1] < 1
624                            let s:nrrw_rgn_lines[instn].start[1] = 1
625                    endif
626                    if s:nrrw_rgn_lines[instn].end[1] < 1
627                            let s:nrrw_rgn_lines[instn].end[1] = 1
628                    endif
629                    call <sid>DeleteMatches(instn)
630                    call <sid>AddMatches(<sid>GeneratePattern(
631                                 \s:nrrw_rgn_lines[instn].start[1:2], 
632                                 \s:nrrw_rgn_lines[instn].end[1:2], 
633                                 \'V'), instn)
634                 endif
635         endfor
636
637 endfun
638
639 fun! <sid>NrrwSettings(on) "{{{1
640         if a:on
641                 setl noswapfile buftype=acwrite foldcolumn=0
642                 setl nobuflisted
643                 let instn = matchstr(bufname(''), '_\zs\d\+')+0
644                 if  !&hidden && !has_key(s:nrrw_rgn_lines[instn], "single")
645                         setl bufhidden=wipe
646                 else
647                         setl bufhidden=hide
648                 endif
649         else
650                 setl swapfile buftype= bufhidden= buflisted
651         endif
652 endfun
653
654 fun! <sid>SetupBufLocalCommands() "{{{1
655         com! -buffer -bang WidenRegion :call nrrwrgn#WidenRegion(<bang>0)
656         com! -buffer NRSyncOnWrite  :call nrrwrgn#ToggleSyncWrite(1)
657         com! -buffer NRNoSyncOnWrite :call nrrwrgn#ToggleSyncWrite(0)
658 endfun
659
660 fun! <sid>ReturnComments() "{{{1
661         let cmt = <sid>ReturnCommentFT()
662         let c_s    = split(cmt)[0]
663         let c_e    = (len(split(cmt)) == 1 ? "" : " ". split(cmt)[1])
664         return [c_s, c_e]
665 endfun
666
667 fun! nrrwrgn#NrrwRgnDoPrepare(...) "{{{1
668         let bang = (a:0 > 0 && !empty(a:1))
669         if !exists("s:nrrw_rgn_line")
670                 call <sid>WarningMsg("You need to first select the lines to".
671                         \ " narrow using :NRP!")
672            return
673         endif
674         if empty(s:nrrw_rgn_line) && !exists("s:nrrw_rgn_buf")
675                 call <sid>WarningMsg("No lines selected from :NRP, aborting!")
676            return
677         endif
678         if !exists("s:nrrw_rgn_buf")
679                 let s:nrrw_rgn_buf =  <sid>ParseList(s:nrrw_rgn_line)
680         endif
681         if empty(s:nrrw_rgn_buf)
682                 call <sid>WarningMsg("An error occured when selecting all lines. Please report as bug")
683                 unlet s:nrrw_rgn_buf
684            return
685    endif
686         let o_lz = &lz
687         let s:o_s  = @/
688         set lz
689         let orig_buf=bufnr('')
690
691         " initialize Variables
692         call <sid>Init()
693     call <sid>CheckProtected()
694         let s:nrrw_rgn_lines[s:instn].start             = []
695         let s:nrrw_rgn_lines[s:instn].end               = []
696         let s:nrrw_rgn_lines[s:instn].multi     = s:nrrw_rgn_buf
697         let s:nrrw_rgn_lines[s:instn].orig_buf  = orig_buf
698         call <sid>DeleteMatches(s:instn)
699
700         let nr=0
701         let lines=[]
702         let buffer=[]
703
704         let keys = keys(s:nrrw_rgn_buf)
705         call sort(keys,"<sid>CompareNumbers")
706         "for [ nr,lines] in items(s:nrrw_rgn_buf)
707         let [c_s, c_e] =  <sid>ReturnComments()
708         for nr in keys
709                 let lines = s:nrrw_rgn_buf[nr]
710                 let start = lines[0]
711                 let end   = len(lines)==2 ? lines[1] : lines[0]
712                 if !bang
713                         call <sid>AddMatches(<sid>GeneratePattern([start,0], [end,0], 'V'),
714                                         \s:instn)
715                 endif
716                 call add(buffer, c_s.' Start NrrwRgn'.nr.c_e)
717                 let buffer = buffer +
718                                 \ getline(start,end) +
719                                 \ [c_s.' End NrrwRgn'.nr.c_e, '']
720         endfor
721
722         let win=<sid>NrrwRgnWin(bang)
723         if bang
724                 let s:nrrw_rgn_lines[s:instn].single = 1
725         endif
726         let b:orig_buf = orig_buf
727         call setline(1, buffer)
728         setl nomod
729         let b:nrrw_instn = s:instn
730         call <sid>SetupBufLocalCommands()
731         call <sid>NrrwRgnAuCmd(0)
732         call <sid>CleanRegions()
733         call <sid>HideNrrwRgnLines()
734
735         " restore settings
736         let &lz   = o_lz
737 endfun
738
739 fun! nrrwrgn#NrrwRgn(...) range  "{{{1
740         let o_lz = &lz
741         let s:o_s  = @/
742         set lz
743         let orig_buf=bufnr('')
744         let bang = (a:0 > 0 && !empty(a:1))
745
746         " initialize Variables
747         call <sid>Init()
748     call <sid>CheckProtected()
749         let first = a:firstline
750         let last  = a:lastline
751         " If first line is in a closed fold,
752         " include complete fold in Narrowed window
753         if first == last && foldclosed(first) != -1
754                 let first = foldclosed(first)
755                 let last  = foldclosedend(last)
756         endif
757         let s:nrrw_rgn_lines[s:instn].start = [ 0, first, 0, 0 ]
758         let s:nrrw_rgn_lines[s:instn].end       = [ 0, last , 0, 0 ]
759         let s:nrrw_rgn_lines[s:instn].orig_buf  = orig_buf
760         let a=getline(
761                 \s:nrrw_rgn_lines[s:instn].start[1], 
762                 \s:nrrw_rgn_lines[s:instn].end[1])
763         call <sid>DeleteMatches(s:instn)
764         let win=<sid>NrrwRgnWin(bang)
765         if bang
766                 let s:nrrw_rgn_lines[s:instn].single = 1
767         else
768                 noa wincmd p
769                 " Set highlighting in original window
770                 call <sid>AddMatches(<sid>GeneratePattern(
771                         \s:nrrw_rgn_lines[s:instn].start[1:2], 
772                         \s:nrrw_rgn_lines[s:instn].end[1:2], 
773                         \'V'), s:instn)
774                 " move back to narrowed window
775                 noa wincmd p
776         endif
777         let b:orig_buf = orig_buf
778         call setline(1, a)
779         setl nomod
780         let b:nrrw_instn = s:instn
781         call <sid>SetupBufLocalCommands()
782         call <sid>NrrwRgnAuCmd(0)
783         if has_key(s:nrrw_aucmd, "create")
784                 exe s:nrrw_aucmd["create"]
785         endif
786         if has_key(s:nrrw_aucmd, "close")
787                 let b:nrrw_aucmd_close = s:nrrw_aucmd["close"]
788         endif
789
790         " restore settings
791         let &lz   = o_lz
792 endfun
793
794 fun! nrrwrgn#Prepare() "{{{1
795         let ltime = localtime()
796         if  (!exists("s:nrrw_rgn_last") || s:nrrw_rgn_last + 10 < ltime)
797                 let s:nrrw_rgn_last = ltime
798                 let s:nrrw_rgn_line = []
799         endif
800         if !exists("s:nrrw_rgn_line") | let s:nrrw_rgn_line=[] | endif
801         call add(s:nrrw_rgn_line, line('.'))
802 endfun
803
804 fun! nrrwrgn#WidenRegion(force)  "{{{1
805         " a:close: original narrowed window is going to be closed
806         " so, clean up, don't renew highlighting, etc.
807         let nrw_buf  = bufnr('')
808         let orig_buf = b:orig_buf
809         let orig_tab = tabpagenr()
810         let instn    = b:nrrw_instn
811         let close    = has_key(s:nrrw_rgn_lines[instn], 'single')
812         let vmode    = has_key(s:nrrw_rgn_lines[instn], 'vmode')
813         " Execute autocommands
814         if has_key(s:nrrw_aucmd, "close")
815                 exe s:nrrw_aucmd["close"]
816         endif
817         let cont         = getline(1,'$')
818
819         let tab=<sid>BufInTab(orig_buf)
820         if tab != tabpagenr() && tab > 0
821                 exe "noa tabn" tab
822         endif
823         let orig_win = bufwinnr(orig_buf)
824         " Should be in the right tab now!
825         if (orig_win == -1)
826                 if bufexists(orig_buf)
827                         " buffer not in current window, switch to it!
828                         exe "noa" orig_buf "b!"
829                         " Make sure highlighting will be removed
830                         let close = (&g:hid ? 0 : 1)
831                 else
832                         call s:WarningMsg("Original buffer does no longer exist!".
833                                                 \ " Aborting!")
834                         return
835                 endif
836         else
837                 exe ':noa'. orig_win. 'wincmd w'
838         endif
839         let _opts = <sid>SaveRestoreRegister([])
840         let wsv=winsaveview()
841         call <sid>DeleteMatches(instn)
842         if exists("b:orig_buf_ro") && b:orig_buf_ro && !a:force
843                 call s:WarningMsg("Original buffer protected. Can't write changes!")
844                 call <sid>JumpToBufinTab(orig_tab, nrw_buf)
845                 return
846         endif
847         if !&l:ma && !( exists("b:orig_buf_ro") && b:orig_buf_ro)
848                 setl ma
849         endif
850         " This is needed to adjust all other narrowed regions
851         " in case we have several narrowed regions within the same buffer
852         if exists("g:nrrw_rgn_protect") && g:nrrw_rgn_protect =~? 'n'
853                 let  adjust_line_numbers = len(cont) - 1 - (
854                                         \s:nrrw_rgn_lines[instn].end[1] - 
855                                         \s:nrrw_rgn_lines[instn].start[1])
856         endif
857
858         " Make sure the narrowed buffer is still valid (happens, when 2 split
859         " window of the narrowed buffer is opened.
860         if !has_key(s:nrrw_rgn_lines, instn)
861                 call <sid>WarningMsg("Error writing changes back,".
862                                         \ "Narrowed Window invalid!")
863                 return
864         endif
865
866         " Now copy the content back into the original buffer
867
868         " 1) Check: Multiselection
869         if has_key(s:nrrw_rgn_lines[instn], 'multi')
870                 call <sid>WidenRegionMulti(cont, instn)
871         " 2) Visual Selection
872         elseif vmode
873                 "charwise, linewise or blockwise selection 
874                 call setreg('a', join(cont, "\n"). "\n",
875                                         \ s:nrrw_rgn_lines[instn].vmode)
876                 if s:nrrw_rgn_lines[instn].vmode == 'v' &&
877                         \ s:nrrw_rgn_lines[instn].end[1] -
878                         \ s:nrrw_rgn_lines[instn].start[1] + 1 == len(cont) + 1
879                    " in characterwise selection, remove trailing \n
880                    call setreg('a', substitute(@a, '\n$', '', ''), 
881                         \ s:nrrw_rgn_lines[instn].vmode)
882                 endif
883                 if v:version > 703 || (v:version == 703 && has("patch590"))
884                         " settable '< and '> marks
885                         let _v = []
886                         " store actual values
887                         let _v = [getpos("'<"), getpos("'>"), [visualmode(1)]]
888                         " set the mode for the gv command
889                         exe "norm! ". s:nrrw_rgn_lines[instn].vmode."\<ESC>"
890                         call setpos("'<", s:nrrw_rgn_lines[instn].start)
891                         call setpos("'>", s:nrrw_rgn_lines[instn].end)
892                         exe 'norm! gv"aP'
893                         if !empty(_v[2][0]) && (_v[2][0] != visualmode())
894                                 exe 'norm!' _v[2][0]. "\<ESC>"
895                                 call setpos("'<", _v[0])
896                                 call setpos("'>", _v[1])
897                         endif
898                 else
899                         exe "keepj" s:nrrw_rgn_lines[instn].start[1]
900                         exe "keepj norm!" s:nrrw_rgn_lines[instn].start[2]. '|'
901                         exe "keepj norm!" s:nrrw_rgn_lines[instn].vmode
902                         exe "keepj" s:nrrw_rgn_lines[instn].end[1]
903                         if s:nrrw_rgn_lines[instn].blockmode
904                                 exe "keepj norm!" s:nrrw_rgn_lines[instn].end[2]. '|'
905                         else
906                                 keepj norm! $
907                         endif
908                         " overwrite the visually selected region with the contents from
909                         " the narrowed buffer
910                         norm! "aP
911                 endif
912                 " Recalculate the start and end positions of the narrowed window
913                 " so subsequent calls will adjust the region accordingly
914                 let [ s:nrrw_rgn_lines[instn].start, 
915                          \s:nrrw_rgn_lines[instn].end ] = <sid>RetVisRegionPos()
916                 " make sure the visual selected lines did not add a new linebreak,
917                 " this messes up the characterwise selected regions and removes lines
918                 " on further writings
919                 if s:nrrw_rgn_lines[instn].end[1] - s:nrrw_rgn_lines[instn].start[1]
920                                 \ + 1 > len(cont) && s:nrrw_rgn_lines[instn].vmode == 'v'
921                         let s:nrrw_rgn_lines[instn].end[1] =
922                                 \ s:nrrw_rgn_lines[instn].end[1] - 1
923                         let s:nrrw_rgn_lines[instn].end[2] = virtcol('$')
924                 endif
925
926                 " also, renew the highlighted region
927                 if !has_key(s:nrrw_rgn_lines[instn], 'single')
928                         call <sid>AddMatches(<sid>GeneratePattern(
929                                 \ s:nrrw_rgn_lines[instn].start[1:2],
930                                 \ s:nrrw_rgn_lines[instn].end[1:2],
931                                 \ s:nrrw_rgn_lines[instn].vmode),
932                                 \ instn)
933                 else
934                         noa b #
935                 endif
936         " 3) :NR started selection
937         else 
938                 " linewise selection because we started the NarrowRegion with the
939                 " command NarrowRegion(0)
940                 "
941                 " if the endposition of the narrowed buffer is also the last line of
942                 " the buffer, the append will add an extra newline that needs to be
943                 " cleared.
944                 if s:nrrw_rgn_lines[instn].end[1]==line('$') &&
945                 \  s:nrrw_rgn_lines[instn].start[1] == 1
946                         let delete_last_line=1
947                 else
948                         let delete_last_line=0
949                 endif
950                 exe ':silent :'.s:nrrw_rgn_lines[instn].start[1].','
951                         \.s:nrrw_rgn_lines[instn].end[1].'d _'
952                 call append((s:nrrw_rgn_lines[instn].start[1]-1),cont)
953                 " Recalculate the start and end positions of the narrowed window
954                 " so subsequent calls will adjust the region accordingly
955                 " so subsequent calls will adjust the region accordingly
956                 let  s:nrrw_rgn_lines[instn].end[1] =
957                         \ s:nrrw_rgn_lines[instn].start[1] + len(cont) -1
958                 if s:nrrw_rgn_lines[instn].end[1] > line('$')
959                         let s:nrrw_rgn_lines[instn].end[1] = line('$')
960                 endif
961                 if !has_key(s:nrrw_rgn_lines[instn], 'single')
962                         call <sid>AddMatches(<sid>GeneratePattern(
963                                 \s:nrrw_rgn_lines[instn].start[1:2], 
964                                 \s:nrrw_rgn_lines[instn].end[1:2], 
965                                 \'V'),
966                                 \instn)
967                 endif
968                 if delete_last_line
969                         silent! $d _
970                 endif
971         endif
972         " Recalculate start- and endline numbers for all other Narrowed Windows.
973         " This matters, if you narrow different regions of the same file and
974         " write your changes back.
975         if exists("g:nrrw_rgn_protect") && g:nrrw_rgn_protect =~? 'n'
976                 call <sid>RecalculateLineNumbers(instn, adjust_line_numbers)
977         endif
978 "       if close && !has_key(s:nrrw_rgn_lines[instn], 'single')
979                 " For narrowed windows that have been created using !,
980                 " don't clean up yet, or else we loose all data and can't write
981                 " it back later.
982                 " (e.g. :NR! createas a new single window, do :sp
983                 "  and you can only write one of the windows back, the other will
984                 "  become invalid, if CleanUp is executed)
985 "       endif
986         call <sid>SaveRestoreRegister(_opts)
987         let  @/=s:o_s
988         call winrestview(wsv)
989         if !close && has_key(s:nrrw_rgn_lines[instn], 'single')
990                 " move back to narrowed buffer
991                 noa b #
992         elseif close
993                 call <sid>CleanUpInstn(instn)
994         endif
995         " jump back to narrowed window
996         call <sid>JumpToBufinTab(orig_tab, nrw_buf)
997         setl nomod
998         if a:force
999                 " trigger auto command
1000                 bw
1001         endif
1002 endfun
1003
1004 fun! nrrwrgn#VisualNrrwRgn(mode, ...) "{{{1
1005         " bang: open the narrowed buffer in the current window and don't open a
1006         " new split window
1007         if empty(a:mode)
1008                 " in case, visual mode wasn't entered, visualmode()
1009                 " returns an empty string and in that case, we finish
1010                 " here
1011                 call <sid>WarningMsg("There was no region visually selected!")
1012                 return
1013         endif
1014         " This beeps, when called from command mode
1015         " e.g. by using :NRV, so using :sil!
1016         " else exiting visual mode
1017         exe "sil! norm! \<ESC>"
1018         let bang = (a:0 > 0 && !empty(a:1))
1019         " stop visualmode
1020         let o_lz = &lz
1021         let s:o_s  = @/
1022         set lz
1023         call <sid>Init()
1024         let s:nrrw_rgn_lines[s:instn].vmode=a:mode
1025         " Protect the original buffer,
1026         " so you won't accidentally modify those lines,
1027         " that will later be overwritten
1028         let orig_buf=bufnr('')
1029         let _opts = <sid>SaveRestoreRegister([])
1030
1031         call <sid>CheckProtected()
1032         let [ s:nrrw_rgn_lines[s:instn].start,
1033                 \s:nrrw_rgn_lines[s:instn].end ] = <sid>RetVisRegionPos()
1034         call <sid>DeleteMatches(s:instn)
1035         norm! gv"ay
1036         if len(split(@a, "\n", 1)) != 
1037                         \ (s:nrrw_rgn_lines[s:instn].end[1] -
1038                         \ s:nrrw_rgn_lines[s:instn].start[1] + 1)
1039                 " remove trailing "\n"
1040                 let @a=substitute(@a, '\n$', '', '') 
1041         endif
1042
1043         if a:mode == '\16' && <sid>CheckRectangularRegion(@a)
1044                 " Rectangular selection
1045                 let s:nrrw_rgn_lines[s:instn].blockmode = 1
1046         else
1047                 " Non-Rectangular selection
1048                 let s:nrrw_rgn_lines[s:instn].blockmode = 0
1049         endif
1050         let win=<sid>NrrwRgnWin(bang)
1051         if bang
1052                 let s:nrrw_rgn_lines[s:instn].single = 1
1053         else
1054                 " Set the highlighting
1055                 noa wincmd p
1056                 call <sid>AddMatches(<sid>GeneratePattern(
1057                                 \s:nrrw_rgn_lines[s:instn].start[1:2],
1058                                 \s:nrrw_rgn_lines[s:instn].end[1:2],
1059                                 \s:nrrw_rgn_lines[s:instn].vmode, 
1060                                 \s:nrrw_rgn_lines[s:instn].blockmode),
1061                                 \s:instn)
1062                 noa wincmd p
1063         endif
1064         let b:orig_buf = orig_buf
1065         let s:nrrw_rgn_lines[s:instn].orig_buf  = orig_buf
1066         silent put a
1067         let b:nrrw_instn = s:instn
1068         silent 0d _
1069         setl nomod
1070         call <sid>SetupBufLocalCommands()
1071         " Setup autocommands
1072         call <sid>NrrwRgnAuCmd(0)
1073         " Execute autocommands
1074         if has_key(s:nrrw_aucmd, "create")
1075                 exe s:nrrw_aucmd["create"]
1076         endif
1077         call <sid>SaveRestoreRegister(_opts)
1078
1079         " restore settings
1080         let &lz   = o_lz
1081 endfun
1082
1083 fun! nrrwrgn#UnifiedDiff() "{{{1
1084         let save_winposview=winsaveview()
1085         let orig_win = winnr()
1086         " close previous opened Narrowed buffers
1087         silent! windo | if bufname('')=~'^Narrow_Region' &&
1088                         \ &diff |diffoff|q!|endif
1089         " minimize Window
1090         " this is disabled, because this might be useful, to see everything
1091         "exe "vert resize -999999"
1092         "setl winfixwidth
1093         " move to current start of chunk of unified diff
1094         if search('^@@', 'bcW') > 0
1095                 call search('^@@', 'bc')
1096         else
1097                 call search('^@@', 'c')
1098         endif
1099         let curpos=getpos('.')
1100         for i in range(2)
1101                 if search('^@@', 'nW') > 0
1102                         .+,/@@/-NR
1103                 else
1104                         " Last chunk in file
1105                         .+,$NR
1106                 endif
1107            " Split vertically
1108            wincmd H
1109            if i==0
1110                    silent! g/^-/d _
1111            else
1112                    silent! g/^+/d _
1113            endif
1114            diffthis
1115            0
1116            exe ":noa wincmd p"
1117            call setpos('.', curpos)
1118         endfor
1119         call winrestview(save_winposview)
1120 endfun
1121
1122 fun! nrrwrgn#ToggleSyncWrite(enable) "{{{1
1123         let s:nrrw_rgn_lines[b:nrrw_instn].disable = !a:enable
1124         " Enable syncing of bufers
1125         if a:enable
1126                 " Enable Narrow settings and autocommands
1127                 call <sid>NrrwSettings(1)
1128                 call <sid>NrrwRgnAuCmd(0)
1129                 setl modified
1130         else
1131                 " Disable Narrow settings and autocommands
1132                 call <sid>NrrwSettings(0)
1133                 " b:nrrw_instn should always be available
1134                 call <sid>NrrwRgnAuCmd(b:nrrw_instn)
1135         endif
1136 endfun
1137
1138 fun! nrrwrgn#LastNrrwRgn(bang) "{{{1
1139         let bang = !empty(a:bang)
1140     if !exists("s:nrrw_rgn_lines") || !has_key(s:nrrw_rgn_lines, 'last')
1141                 call <sid>WarningMsg("There is no last region to re-select")
1142            return
1143         endif
1144         let orig_buf = s:nrrw_rgn_lines['last'][0][0] + 0
1145         let tab = <sid>BufInTab(orig_buf)
1146         if tab != tabpagenr() && tab > 0
1147                 exe "tabn" tab
1148         endif
1149         let orig_win = bufwinnr(orig_buf)
1150         " Should be in the right tab now!
1151         if (orig_win == -1)
1152                 call s:WarningMsg("Original buffer does no longer exist! Aborting!")
1153                 return
1154         endif
1155         if orig_win != winnr()
1156                 exe "noa" orig_win "wincmd w"
1157         endif
1158         if len(s:nrrw_rgn_lines['last']) == 1
1159                 " Multi Narrowed
1160                 let s:nrrw_rgn_buf =  s:nrrw_rgn_lines['last'][0][1]
1161                 call nrrwrgn#NrrwRgnDoPrepare('')
1162         else
1163                 exe "keepj" s:nrrw_rgn_lines['last'][0][1][0]
1164                 exe "keepj norm!" s:nrrw_rgn_lines['last'][0][1][1]. '|'
1165                 " Start visual mode
1166                 exe "keepj norm!" s:nrrw_rgn_lines['last'][2]
1167                 exe "keepj" s:nrrw_rgn_lines['last'][1][1][0]
1168                 if col(s:nrrw_rgn_lines['last'][1][1][1]) == col('$') &&
1169                 \ s:nrrw_rgn_lines['last'][2] == '\16'
1170                         " Best guess
1171                         exe "keepj $"
1172                 else
1173                         exe "keepj norm!" s:nrrw_rgn_lines['last'][1][1][1]. '|'
1174                 endif
1175                 " Call VisualNrrwRgn()
1176                 call nrrwrgn#VisualNrrwRgn(visualmode(), bang)
1177         endif
1178 endfu
1179 " Debugging options "{{{1
1180 fun! nrrwrgn#Debug(enable) "{{{1
1181         if (a:enable)
1182                 let s:debug=1
1183                 fun! <sid>NrrwRgnDebug() "{{{2
1184                         "sil! unlet s:instn
1185                         com! NI :call <sid>WarningMsg("Instance: ".s:instn)
1186                         com! NJ :call <sid>WarningMsg("Data: ".string(s:nrrw_rgn_lines))
1187                         com! -nargs=1 NOutput :if exists("s:".<q-args>)|redraw!|
1188                                                 \ :exe 'echo s:'.<q-args>|else|
1189                                                 \ echo "s:".<q-args>. " does not exist!"|endif
1190                 endfun
1191                 call <sid>NrrwRgnDebug()
1192         else
1193                 let s:debug=0
1194                 delf <sid>NrrwRgnDebug
1195                 delc NI
1196                 delc NJ
1197                 delc NOutput
1198         endif
1199 endfun
1200
1201 " Modeline {{{1
1202 " vim: ts=4 sts=4 fdm=marker com+=l\:\" fdl=0