1
Files
flake-nixinator/config/neovim/store/lazy-plugins/NrrwRgn/NrrwRgn.vmb

2464 lines
86 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

" Vimball Archiver by Charles E. Campbell
UseVimball
finish
plugin/NrrwRgn.vim [[[1
90
" NrrwRgn.vim - Narrow Region plugin for Vim
" -------------------------------------------------------------
" Version: 0.33
" Maintainer: Christian Brabandt <cb@256bit.org>
" Last Change: Thu, 15 Jan 2015 20:52:29 +0100
" Script: http://www.vim.org/scripts/script.php?script_id=3075
" Copyright: (c) 2009-2015 by Christian Brabandt
" The VIM LICENSE applies to NrrwRgn.vim
" (see |copyright|) except use "NrrwRgn.vim"
" instead of "Vim".
" No warranty, express or implied.
" *** *** Use At-Your-Own-Risk! *** ***
" GetLatestVimScripts: 3075 33 :AutoInstall: NrrwRgn.vim
"
" Init: {{{1
let s:cpo= &cpo
if exists("g:loaded_nrrw_rgn") || &cp
finish
endif
set cpo&vim
let g:loaded_nrrw_rgn = 1
" Debug Setting
let s:debug=0
if s:debug
exe "call nrrwrgn#Debug(1)"
endif
" ----------------------------------------------------------------------------
" Public Interface: {{{1
" plugin functions "{{{2
fun! <sid>NrrwRgnOp(type, ...) " {{{3
" used for operator function mapping
let sel_save = &selection
let &selection = "inclusive"
if a:0 " Invoked from Visual mode, use '< and '> marks.
sil exe "normal! `<" . a:type . "`>y"
elseif a:type == 'line'
sil exe "normal! '[V']y"
elseif a:type == 'block'
sil exe "normal! `[\<C-V>`]y"
else
sil exe "normal! `[v`]y"
endif
call nrrwrgn#NrrwRgn(visualmode(), '')
let &selection = sel_save
endfu
" Define the Command aliases "{{{2
com! -range -bang NRPrepare :<line1>,<line2>NRP<bang>
com! -bang -range NarrowRegion :<line1>,<line2>NR
com! -bang NRMulti :NRM<bang>
com! -bang NarrowWindow :NW
com! -bang NRLast :NRL
" Define the actual Commands "{{{2
com! -range -bang NR :<line1>, <line2>call nrrwrgn#NrrwRgn('',<q-bang>)
com! -range -bang NRP :<line1>, <line2>call nrrwrgn#Prepare(<q-bang>)
com! -bang -range NRV :call nrrwrgn#NrrwRgn(visualmode(), <q-bang>)
com! NUD :call nrrwrgn#UnifiedDiff()
com! -bang NW :exe ":" . line('w0') . ',' . line('w$') . "call nrrwrgn#NrrwRgn(0,<q-bang>)"
com! -bang NRM :call nrrwrgn#NrrwRgnDoMulti(<q-bang>)
com! -bang NRL :call nrrwrgn#LastNrrwRgn(<q-bang>)
" Define the Mapping: "{{{2
if !hasmapto('<Plug>NrrwrgnDo') && !get(g:, 'nrrw_rgn_nomap_nr', 0)
xmap <unique> <Leader>nr <Plug>NrrwrgnDo
nmap <unique> <Leader>nr <Plug>NrrwrgnDo
endif
if !hasmapto('<Plug>NrrwrgnBangDo') && !get(g:, 'nrrw_rgn_nomap_Nr', 0)
xmap <unique> <Leader>Nr <Plug>NrrwrgnBangDo
endif
if !hasmapto('VisualNrrwRgn')
xnoremap <unique> <script> <Plug>NrrwrgnDo <sid>VisualNrrwRgn
nnoremap <unique> <script> <Plug>NrrwrgnDo <sid>VisualNrrwRgn
endif
if !hasmapto('VisualNrrwRgnBang')
xnoremap <unique> <script> <Plug>NrrwrgnBangDo <sid>VisualNrrwBang
endif
xnoremap <sid>VisualNrrwRgn :<c-u>call nrrwrgn#NrrwRgn(visualmode(),'')<cr>
xnoremap <sid>VisualNrrwBang :<c-u>call nrrwrgn#NrrwRgn(visualmode(),'!')<cr>
" operator function
nnoremap <sid>VisualNrrwRgn :set opfunc=<sid>NrrwRgnOp<cr>g@
" Restore: "{{{1
let &cpo=s:cpo
unlet s:cpo
" vim: ts=4 sts=4 fdm=marker com+=l\:\"
autoload/nrrwrgn.vim [[[1
1572
" nrrwrgn.vim - Narrow Region plugin for Vim
" -------------------------------------------------------------
" Version: 0.33
" Maintainer: Christian Brabandt <cb@256bit.org>
" Last Change: Thu, 15 Jan 2015 20:52:29 +0100
" Script: http://www.vim.org/scripts/script.php?script_id=3075
" Copyright: (c) 2009-2015 by Christian Brabandt
" The VIM LICENSE applies to NrrwRgn.vim
" (see |copyright|) except use "NrrwRgn.vim"
" instead of "Vim".
" No warranty, express or implied.
" *** *** Use At-Your-Own-Risk! *** ***
" GetLatestVimScripts: 3075 33 :AutoInstall: NrrwRgn.vim
"
" Functions:
let s:numeric_sort = v:version > 704 || v:version == 704 && has("patch341")
let s:getcurpos = exists('*getcurpos')
let s:window_type = {"source": 0, "target": 1}
fun! <sid>WarningMsg(msg) abort "{{{1
let msg = "NarrowRegion: ". a:msg
echohl WarningMsg
if exists(":unsilent") == 2
unsilent echomsg msg
else
echomsg msg
endif
sleep 1
echohl Normal
let v:errmsg = msg
endfun
fun! <sid>Init() abort "{{{1
if !exists("s:opts")
" init once
let s:opts = []
endif
if !exists("s:instn")
let s:instn=1
if !exists("g:nrrw_custom_options") || empty(g:nrrw_custom_options)
let s:opts=<sid>Options('local to buffer')
endif
else
" Prevent accidently overwriting windows with instn_id set
" back to an already existing instn_id
let s:instn = (s:instn==0 ? 1 : s:instn)
while (has_key(s:nrrw_rgn_lines, s:instn))
let s:instn+=1
endw
endif
call <sid>SetupHooks()
if !exists("s:nrrw_rgn_lines")
let s:nrrw_rgn_lines = {}
endif
let s:nrrw_rgn_lines[s:instn] = {}
" show some debugging messages
let s:nrrw_winname='NrrwRgn'
" Customization
let s:nrrw_rgn_vert = get(g:, 'nrrw_rgn_vert', 0)
let s:nrrw_rgn_wdth = get(g:, 'nrrw_rgn_wdth', 20)
let s:nrrw_rgn_hl = get(g:, 'nrrw_rgn_hl', 'WildMenu')
let s:nrrw_rgn_nohl = get(g:, 'nrrw_rgn_nohl', 0)
let s:debug = (exists("s:debug") ? s:debug : 0)
let s:float = has('float')
let s:syntax = has('syntax')
if v:version < 704
call s:WarningMsg('NrrwRgn needs Vim > 7.4 or it might not work correctly')
endif
endfun
fun! <sid>SetupHooks() abort "{{{1
if !exists("s:nrrw_aucmd")
let s:nrrw_aucmd = {}
endif
if exists("b:nrrw_aucmd_create")
let s:nrrw_aucmd["create"] = b:nrrw_aucmd_create
endif
if exists("b:nrrw_aucmd_close")
let s:nrrw_aucmd["close"] = b:nrrw_aucmd_close
endif
if get(g:, 'nrrw_rgn_write_on_sync', 0)
let b:nrrw_aucmd_written = get(b:, 'nrrw_aucmd_written', ''). '|:w'
endif
endfun
fun! <sid>NrrwRgnWin(bang) abort "{{{1
" Create new scratch window
if has_key(s:nrrw_rgn_lines, s:instn) &&
\ has_key(s:nrrw_rgn_lines[s:instn], 'multi')
let bufname = 'multi'
else
let bufname = matchstr(substitute(expand('%:t:r'), ' ', '_', 'g'), '^.\{0,8}')
endif
let nrrw_winname = s:nrrw_winname. '_'. bufname . '_'. s:instn
let nrrw_win = bufwinnr('^'.nrrw_winname.'$')
if nrrw_win != -1
exe ":noa ". nrrw_win. 'wincmd w'
" just in case, a global nomodifiable was set
" disable this for the narrowed window
setl ma noro
silent %d _
else
if !exists('g:nrrw_topbot_leftright')
let g:nrrw_topbot_leftright = 'topleft'
endif
let nrrw_rgn_direction = (s:nrrw_rgn_vert ? 'vsp' : 'sp')
if get(g:, 'nrrw_rgn_equalalways', &equalalways)
let cmd=printf(':noa %s %s %s', g:nrrw_topbot_leftright,
\ nrrw_rgn_direction,
\ nrrw_winname)
else
let nrrw_rgn_size = (s:nrrw_rgn_vert ? winwidth(0) : winheight(0))/2
let cmd=printf(':noa %s %d%s %s', g:nrrw_topbot_leftright,
\ nrrw_rgn_size,
\ nrrw_rgn_direction,
\ nrrw_winname)
endif
if !a:bang
exe cmd
else
try
enew
if bufexists(s:nrrw_winname. '_'. s:instn)
" avoid E95
exe 'bw' s:nrrw_winname. '_'. s:instn
endif
exe 'f' s:nrrw_winname. '_'. s:instn
catch /^Vim\%((\a\+)\)\=:E37/ " catch error E37
" Fall back and use a new window
exe cmd
endtry
endif
" just in case, a global nomodifiable was set
" disable this for the narrowed window
setl ma noro
" Just in case
silent %d _
" Set up some options like 'bufhidden', 'noswapfile',
" 'buftype', 'bufhidden', when enabling Narrowing.
call <sid>NrrwSettings(1)
let nrrw_win = bufwinnr("")
endif
" focus: target
" set window variables
let w:nrrw_rgn_id = s:instn
let w:nrrw_rgn_id_type = s:window_type["target"]
if !a:bang
noa wincmd p
" focus: source window
let w:nrrw_rgn_id = s:instn
let w:nrrw_rgn_id_type = s:window_type["source"]
noa wincmd p
" focus: target window
endif
" We are in the narrowed buffer now!
return nrrw_win
endfun
fun! <sid>CleanRegions() abort "{{{1
let s:nrrw_rgn_line={}
unlet! s:nrrw_rgn_buf
endfun
fun! <sid>CompareNumbers(a1,a2) abort "{{{1
return (a:a1+0) == (a:a2+0) ? 0 : (a:a1+0) > (a:a2+0) ? 1 : -1
endfun
fun! <sid>ParseList(dict) "{{{1
" for a given list of line numbers, return those line numbers
" in a format start:end for continous items, else [start, next]
" returns a dict of dict: dict[buf][1]=[1,10], dict[buf][2]=[15,20]
let outdict = {}
let i=1
let list = a:dict
for buf in sort(keys(a:dict), (s:numeric_sort ? 'n' : '<sid>CompareNumbers'))
let result = {}
let start = 0
let temp = 0
let item = 0
for item in sort(list[buf], (s:numeric_sort ? 'n' : "<sid>CompareNumbers"))
if start==0
let start=item
elseif temp!=item-1
if has_key(result, i)
let i+=1
endif
let result[i]=[start,temp]
let start=item
endif
let temp=item
endfor
if empty(result)
" add all items from the list to the result
" list consists only of consecutive items
let result[i] = [list[buf][0], list[buf][-1]]
endif
" Make sure the last item is included in the selection
if get(result, i, 0)[0] && result[i][1] != item
let i+=1
let result[i]=[start,item]
endif
let outdict[buf] = result
let i+=1
endfor
return outdict
endfun
fun! <sid>GoToWindow(buffer, instn, type) abort "{{{1
" find correct window and switch to it
" should be called from correct tab page
for win in range(1,winnr('$'))
exe ':noa '. win. 'wincmd w'
if get(w:, 'nrrw_rgn_id', 0) == a:instn && get(w:, 'nrrw_rgn_id_type', -1) == a:type
break
endif
endfor
if bufnr('') == a:buffer
return
else
exe ":noa ". a:buffer. "b"
endif
endfun
fun! <sid>WriteNrrwRgn(...) abort "{{{1
" if argument is given, write narrowed buffer back
" else destroy the narrowed window
let nrrw_instn = exists("b:nrrw_instn") ? b:nrrw_instn : s:instn
if exists("b:orig_buf") && (bufwinnr(b:orig_buf) == -1) &&
\ !<sid>BufInTab(b:orig_buf) &&
\ !bufexists(b:orig_buf)
call s:WarningMsg("Original buffer does no longer exist! Aborting!")
return
endif
if exists("a:1") && a:1
" Write the buffer back to the original buffer
let _wsv = winsaveview()
setl nomod
exe ":WidenRegion"
if bufname('') !~# 'NrrwRgn' && bufwinnr(s:nrrw_winname. '_'. s:instn) > 0
exe ':noa'. bufwinnr(s:nrrw_winname. '_'. s:instn). 'wincmd w'
endif
" prevent E315
call winrestview(_wsv)
else
call <sid>StoreLastNrrwRgn(nrrw_instn)
" b:orig_buf might not exists (see issue #2)
let winnr = (exists("b:orig_buf") ? bufwinnr(b:orig_buf) : 0)
" Best guess
if bufname('') =~# 'NrrwRgn' && winnr == -1 && exists("b:orig_buf") &&
\ bufexists(b:orig_buf)
exe ':noa '. b:orig_buf. 'b'
elseif bufname('') =~# 'NrrwRgn' && winnr > 0
exe ':noa'. winnr. 'wincmd w'
endif
" close narrowed buffer
call <sid>NrrwRgnAuCmd(nrrw_instn)
endif
endfun
fun! <sid>SaveRestoreRegister(values) abort "{{{1
if empty(a:values)
" Save
let reg = ['a', getreg('a'), getregtype('a') ]
let fold = [ &fen, &l:fdm ]
if &fen
setl nofoldenable
endif
let visual = [getpos("'<"), getpos("'>")]
return [ reg, fold, visual ]
else
" Restore
call call('setreg', a:values[0])
if a:values[1][0]
let [&l:fen, &l:fdm]=a:values[1]
endif
call setpos("'<", a:values[2][0])
call setpos("'>", a:values[2][1])
endif
endfun
fun! <sid>UpdateOrigWin() abort "{{{
" Tries to keep the original windo in the same viewport, that
" is currently being edited in the narrowed window
if !get(g:, 'nrrw_rgn_update_orig_win', 0)
return
endif
if bufname('') !~# 'NrrwRgn'
return
else
let instn = b:nrrw_instn
endif
if !has_key(s:nrrw_rgn_lines[instn], 'multi')
return
endif
if exists("b:orig_buf") && (bufwinnr(b:orig_buf) == -1) &&
\ !<sid>BufInTab(b:orig_buf) &&
\ !bufexists(b:orig_buf)
" Buffer does not exists anymore (shouldn't happen)
return
endif
let cur_win = winnr()
try
if !exists("b:nrrw_rgn_prev_pos")
let b:nrrw_rgn_prev_pos = getpos(".")
endif
if b:nrrw_rgn_prev_pos[0] == line('.')
return
endif
" Try to update the original window
let start = search(' Start NrrwRgn\d\+', 'bcWn')
if start == 0
" not found
return
endif
let region = matchstr(getline(start),
\ ' Start NrrwRgn\zs\d\+\ze')+0
let offset = line('.') - start
exe ":noa" bufwinnr(b:orig_buf). 'wincmd w'
let pos = s:nrrw_rgn_lines[instn].multi[region]
if pos[0] + offset > pos[1]
" safety check
let offset = pos[1] - pos[0]
endif
call cursor(pos[0]+offset, pos[1])
redraw
finally
exe ":noa" cur_win "wincmd w"
let b:nrrw_rgn_prev_pos = getpos(".")
endtry
endfun!
fun! <sid>SetupBufWriteCmd(instn) "{{{1
if !exists("#NrrwRgn".a:instn."#BufWriteCmd#<buffer>")
if s:debug
echo "Setting up BufWriteCmd!"
endif
au BufWriteCmd <buffer> nested :call s:WriteNrrwRgn(1)
endif
endfu
fun! <sid>SetupBufWinLeave(instn) "{{{1
if !exists("#NrrwRgn".a:instn."#BufWinLeave#<buffer>") &&
\ exists("b:orig_buf") && bufloaded(b:orig_buf)
au BufWinLeave <buffer> :call s:NRBufWinLeave(b:nrrw_instn)
endif
endfu
fun! <sid>NRBufWinLeave(instn) "{{{1
let nrw_buf = bufnr('')
let orig_win = winnr()
let instn = a:instn
let orig_buf = b:orig_buf
let orig_tab = tabpagenr()
call <sid>JumpToBufinTab(<sid>BufInTab(orig_buf), orig_buf, instn, s:window_type["source"])
if !&modifiable
set modifiable
endif
call s:DeleteMatches(instn)
call <sid>JumpToBufinTab(orig_tab, nrw_buf, instn, s:window_type["target"])
endfu
fun! <sid>NrrwRgnAuCmd(instn) abort "{{{1
" If a:instn==0, then enable auto commands
" else disable auto commands for a:instn
if !a:instn
exe "aug NrrwRgn". b:nrrw_instn
au!
"au BufWriteCmd <buffer> nested :call s:WriteNrrwRgn(1)
" don't clean up on BufWinLeave autocommand, that breaks
" :b# and returning back to that buffer later (see issue #44)
au BufWipeout,BufDelete <buffer> nested
\ :call s:WriteNrrwRgn()
au CursorMoved <buffer> :call s:UpdateOrigWin()
" When switching buffer in the original buffer,
" make sure the highlighting of the narrowed buffer will
" be removed"
call s:SetupBufWinLeave(b:nrrw_instn)
call s:SetupBufWriteCmd(b:nrrw_instn)
aug end
au BufWinEnter <buffer> call s:SetupBufWriteCmd(b:nrrw_instn)
else
exe "aug NrrwRgn". a:instn
au!
aug end
exe "aug! NrrwRgn". a:instn
if !has_key(s:nrrw_rgn_lines, a:instn)
" narrowed buffer was already cleaned up
call <sid>DeleteMatches(a:instn)
call s:WarningMsg("Window was already cleaned up. Nothing to do.")
return
endif
" make the original buffer modifiable, if possible
let buf = s:nrrw_rgn_lines[a:instn].orig_buf
if !getbufvar(buf, '&l:ma') && !getbufvar(buf, 'orig_buf_ro')
call setbufvar(s:nrrw_rgn_lines[a:instn].orig_buf, '&ma', 1)
endif
if s:debug
echo printf("bufnr: %d a:instn: %d\n", bufnr(''), a:instn)
echo "bwipe " s:nrrw_winname. '_'. a:instn
endif
if (!has_key(s:nrrw_rgn_lines[a:instn], 'disable') ||
\ (has_key(s:nrrw_rgn_lines[a:instn], 'disable') &&
\ !s:nrrw_rgn_lines[a:instn].disable ))
" Skip to original window and remove highlighting
call <sid>GoToWindow(buf, a:instn, s:window_type["source"])
call <sid>DeleteMatches(a:instn)
unlet! w:nrrw_rgn_id w:nrrw_rgn_id_type
call <sid>CleanUpInstn(a:instn)
endif
endif
endfun
fun! <sid>CleanUpInstn(instn) abort "{{{1
if s:instn>=1 && has_key(s:nrrw_rgn_lines, a:instn)
unlet s:nrrw_rgn_lines[a:instn]
let s:instn-=1
endif
endfu
fun! <sid>StoreLastNrrwRgn(instn) abort "{{{1
" Only store the last region, when the narrowed instance is still valid
if !has_key(s:nrrw_rgn_lines, a:instn)
call <sid>WarningMsg("Error storing the last Narrowed Window, it's invalid!")
return
endif
let s:nrrw_rgn_lines['last'] = []
if !exists("b:orig_buf")
let orig_buf = s:nrrw_rgn_lines[a:instn].orig_buf
else
let orig_buf = b:orig_buf
endif
if has_key(s:nrrw_rgn_lines[a:instn], 'multi')
call add(s:nrrw_rgn_lines['last'], [ orig_buf,
\ s:nrrw_rgn_lines[a:instn]['multi']])
else
" Linewise narrowed region, pretend it was done like a visual
" narrowed region
let s:nrrw_rgn_lines['last'] = [ [ orig_buf,
\ s:nrrw_rgn_lines[a:instn].start[1:]],
\ [ orig_buf, s:nrrw_rgn_lines[a:instn].end[1:]]]
call add(s:nrrw_rgn_lines['last'],
\ has_key(s:nrrw_rgn_lines[a:instn], 'vmode') ?
\ s:nrrw_rgn_lines[a:instn].vmode : 'V')
endif
endfu
fun! <sid>RetVisRegionPos() abort "{{{1
let a = getpos("'<")
let b = getpos("'>")
let a[2] = virtcol("'<")
let b[2] = virtcol("'>")
return [a, b]
endfun
fun! <sid>GeneratePattern(startl, endl, mode) abort "{{{1
" This is just a best guess, the highlighted block could still be wrong
" There are basically two ways, highlighting works in block mode:
" 1) only highlight the block
" 2) highlighty from the beginnning until the end of lines (happens,
" intermediate lines are shorter than block width)
if exists("s:curswant") && s:curswant == 2147483647 &&
\ a:startl[0] > 0 && a:startl[1] > 0 && a:mode ==# ''
unlet! s:curswant
return '\%>'. (a:startl[0]-1). 'l\&\%>'. (a:startl[1]-1).
\ 'v\&\%<'. (a:endl[0]+1). 'l'
elseif a:mode ==# '' && a:startl[0] > 0 && a:startl[1] > 0
return '\%>'. (a:startl[0]-1). 'l\&\%>'. (a:startl[1]-1).
\ 'v\&\%<'. (a:endl[0]+1). 'l\&\%<'. (a:endl[1]+1). 'v'
elseif a:mode ==# 'v' && a:startl[0] > 0 && a:startl[1] > 0
" Easy way: match within a line
if a:startl[0] == a:endl[0]
return '\%'.a:startl[0]. 'l\%>'.(a:startl[1]-1).'v.*\%<'.(a:endl[1]+1).'v'
else
" Need to generate concat 3 patterns:
" 1) from startline, startcolumn till end of line
" 2) all lines between startline and end line
" 3) from start of endline until end column
"
" example: Start at line 1 col. 6 until line 3 column 12:
" \%(\%1l\%>6v.*\)\|\(\%>1l\%<3l.*\)\|\(\%3l.*\%<12v\)
return '\%(\%'. (a:startl[0]). 'l\%>'. (a:startl[1]-1). 'v.*\)\|'.
\ '\%(\%>'. (a:startl[0]). 'l\%<'. (a:endl[0]). 'l.*\)\|'.
\ '\%(\%'. (a:endl[0]). 'l.*\%<'. (a:endl[1]+1). 'v\)'
endif
elseif a:startl[0] > 0
return '\%>'. (a:startl[0]-1). 'l\&\%<'. (a:endl[0]+1). 'l'
else
return ''
endif
endfun
fun! <sid>Options(search) abort "{{{1
" return buffer local options (generated from $VIMRUNTIME/doc/options.txt
return
\ ['autoindent', 'autoread', 'balloonexpr', 'binary', 'bomb',
\ 'cindent', 'cinkeys', 'cinoptions', 'cinwords', 'commentstring',
\ 'complete', 'completefunc', 'copyindent', 'cryptmethod', 'define',
\ 'dictionary', 'endofline', 'equalprg', 'errorformat', 'expandtab',
\ 'fileencoding', 'filetype', 'formatoptions', 'formatlistpat',
\ 'formatexpr', 'iminsert', 'imsearch', 'include', 'includeexpr',
\ 'indentexpr', 'indentkeys', 'infercase', 'key', 'keymap', 'lisp',
\ 'makeprg', 'matchpairs', 'nrformats', 'omnifunc', 'osfiletype',
\ 'preserveindent', 'quoteescape', 'shiftwidth', 'shortname', 'smartindent',
\ 'softtabstop', 'spellcapcheck', 'spellfile', 'spelllang', 'suffixesadd',
\ 'synmaxcol', 'syntax', 'tabstop', 'textwidth', 'thesaurus', 'wrapmargin']
" old function, only used to generate above list
let c=[]
let buf=bufnr('')
try
" empty search pattern
if empty(a:search)
return c
endif
silent noa sview $VIMRUNTIME/doc/options.txt
" for whatever reasons $VIMRUNTIME/doc/options.txt
" does not exist, return empty list
if line('$') == 1
return c
endif
keepj 0
let reg_a=[]
call add(reg_a, 'a')
call add(reg_a,getreg('a'))
call add(reg_a, getregtype('a'))
let @a=''
exe "silent :g/". '\v'.escape(a:search, '\\/'). "/-y A"
let b=split(@a, "\n")
call call('setreg', reg_a)
"call setreg('a', reg_a[0], reg_a[1])
call filter(b, 'v:val =~ "^''"')
" the following options should be set
let filter_opt='\%(modifi\%(ed\|able\)\|readonly\|swapfile\|'.
\ 'buftype\|bufhidden\|foldcolumn\|buflisted\|undofile\)'
call filter(b, 'v:val !~ "^''".filter_opt."''"')
for item in b
let item=substitute(item, '''', '', 'g')
call add(c, split(item, '\s\+')[0])
endfor
finally
if fnamemodify(bufname(''),':p') ==
\expand("$VIMRUNTIME/doc/options.txt")
noa bwipe
endif
exe "noa " bufwinnr(buf) "wincmd w"
return c
endtry
endfun
fun! <sid>GetOptions(opt) abort "{{{1
if exists("g:nrrw_custom_options") && !empty(g:nrrw_custom_options)
let result = g:nrrw_custom_options
else
let result={}
for item in a:opt
try
exe "let result[item]=&l:".item
catch
" no-op, just silence the error
endtry
endfor
endif
return result
endfun
fun! <sid>SetOptions(opt) abort "{{{1
if type(a:opt) == type({})
for [option, result] in items(a:opt)
exe "let &l:". option " = " string(result)
endfor
endif
setl nomod noro
endfun
fun! <sid>CheckProtected() abort "{{{1
" Protect the original window, unless the user explicitly defines not to
" protect it
if exists("g:nrrw_rgn_protect") && g:nrrw_rgn_protect =~? 'n'
return
endif
let b:orig_buf_ro=0
if !&l:ma || &l:ro
let b:orig_buf_ro=1
call s:WarningMsg("Buffer is protected, won't be able to write the changes back!")
else
" Protect the original buffer,
" so you won't accidentally modify those lines,
" that might later be overwritten
setl noma
endif
endfun
fun! <sid>HasMatchID(instn) abort "{{{1
if exists("s:nrrw_rgn_lines[a:instn].matchid")
let id = s:nrrw_rgn_lines[a:instn].matchid
for val in getmatches()
if match(id, val.id) > -1
return 1
endif
endfor
endif
return 0
endfun
fun! <sid>DeleteMatches(instn) abort "{{{1
if exists("s:nrrw_rgn_lines[a:instn].matchid")
" if you call :NarrowRegion several times, without widening
" the previous region, b:matchid might already be defined so
" make sure, the previous highlighting is removed.
for item in s:nrrw_rgn_lines[a:instn].matchid
if item > 0
" If the match has been deleted, discard the error
try
call matchdelete(item)
call remove(s:nrrw_rgn_lines[a:instn].matchid, 0)
catch
" id not found ignore
endtry
endif
endfor
endif
endfun
fun! <sid>HideNrrwRgnLines() abort "{{{1
let char1 = <sid>ReturnComments()[0]
let char1 = escape(char1, '"\\')
let cmd='syn match NrrwRgnStart "^'.char1.' Start NrrwRgn\d\+$"'
exe cmd
let cmd='syn match NrrwRgnEnd "^'.char1.' End NrrwRgn\d\+$"'
exe cmd
exe 'syn region NrrwRgn '.
\ ' start="^\ze'. char1.' Start NrrwRgn"'.
\ ' skip="'.char1.' Start NrrwRgn\(\d\+\)\_.\{-}End NrrwRgn\1$"'.
\ ' end="^$" fold transparent'
hi default link NrrwRgnStart Comment
hi default link NrrwRgnEnd Comment
setl fdm=syntax
endfun
fun! <sid>ReturnCommentFT() abort "{{{1
if !empty(&l:commentstring)
return substitute(&l:commentstring, '%s', ' ', '')
else
return "# "
endif
endfun
fun! <sid>WidenRegionMulti(content, instn) abort "{{{1
" for single narrowed windows, the original narrowed buffer will be closed,
" so don't renew the highlighting and clean up (later in
" nrrwrgn#WidenRegion)
if empty(s:nrrw_rgn_lines[a:instn].multi)
return
endif
" we are not yet in the correct buffer, start loading it
let _hid = &hidden
set hidden
let c_win = winnr()
let c_buf = bufnr('')
" let's pretend, splitting windows is always possible .... :(
noa new
let s_win = winnr()
for buf in sort(keys(s:nrrw_rgn_lines[a:instn].multi), '<sid>CompareNumbers')
exe "noa ". (buf+0). "b"
let _list = []
for item in ['ma', 'ro']
call add(_list, printf("let &l:%s=%s", item, get(g:, '&l:'.item)))
endfor
setl ma noro
let output= []
let list = []
let [c_s, c_e] = <sid>ReturnComments()
let lastline = line('$')
" We must put the regions back from top to bottom,
" otherwise, changing lines in between messes up the
" list of lines that still need to put back from the
" narrowed buffer to the original buffer
for key in sort(keys(s:nrrw_rgn_lines[a:instn].multi[buf]),
\ (s:numeric_sort ? 'n' : "<sid>CompareNumbers"))
let adjust = line('$') - lastline
let range = s:nrrw_rgn_lines[a:instn].multi[buf][key]
let last = (len(range)==2) ? range[1] : range[0]
let first = range[0]
let pattern = printf("%s %%s %s %s %s%s", c_s, "NrrwRgn".key,
\ "buffer:", simplify(bufname(buf+0)), c_e)
let indexs = index(a:content, printf(pattern, 'Start')) + 1
let indexe = index(a:content, printf(pattern, 'End')) - 1
if indexs <= 0 || indexe < -1
call s:WarningMsg("Skipping Region ". key)
continue
endif
" Adjust line numbers. Changing the original buffer, might also
" change the regions we have remembered. So we must adjust these
" numbers.
" This only works, if we put the regions from top to bottom!
let first += adjust
let last += adjust
if last == line('$') && first == 1
let delete_last_line=1
else
let delete_last_line=0
endif
exe ':silent :'. first. ','. last. 'd _'
call append((first-1), a:content[indexs : indexe])
" Recalculate the start and end positions of the narrowed window
" so subsequent calls will adjust the region accordingly
let last = first + len(a:content[indexs : indexe]) - 1
if last > line('$')
let last = line('$')
endif
if !has_key(s:nrrw_rgn_lines[a:instn].multi, 'single')
" original narrowed buffer is going to be closed
" so don't renew the matches
call <sid>AddMatches(<sid>GeneratePattern([first, 0 ],
\ [last, 0], 'V'), a:instn)
endif
if delete_last_line
silent! $d _
endif
endfor
for item in _list
exe item
endfor
endfor
if !_hid
set nohidden
endif
" remove scratch window
exe ":noa ".s_win."wincmd c"
endfun
fun! <sid>AddMatches(pattern, instn) abort "{{{1
if !s:nrrw_rgn_nohl || empty(a:pattern)
if !exists("s:nrrw_rgn_lines[a:instn].matchid")
let s:nrrw_rgn_lines[a:instn].matchid=[]
endif
call add(s:nrrw_rgn_lines[a:instn].matchid,
\matchadd(s:nrrw_rgn_hl, a:pattern))
endif
endfun
fun! <sid>BufInTab(bufnr) abort "{{{1
" returns tabpage of buffer a:bufnr
for tab in range(1,tabpagenr('$'))
if !empty(filter(tabpagebuflist(tab), 'v:val == a:bufnr'))
return tab
endif
endfor
return 0
endfun
fun! <sid>JumpToBufinTab(tab,buf,instn,type) abort "{{{1
" Type is s:window_type["source"] or s:window_type["target"] and checks for
" w:nrrw_rgn_source_win or w:nrrw_rgn_target_win variable
if a:tab && a:tab != tabpagenr()
exe "noa tabn" a:tab
endif
call <sid>GoToWindow(a:buf, a:instn, a:type)
endfun
fun! <sid>RecalculateLineNumbers(instn, adjust) abort "{{{1
" This only matters, if the original window isn't protected
if !exists("g:nrrw_rgn_protect") || g:nrrw_rgn_protect !~# 'n'
return
endif
for instn in filter(keys(s:nrrw_rgn_lines), 'v:val != a:instn')
" Skip narrowed instances, when they are before
" the region, we are currently putting back
if s:nrrw_rgn_lines[instn].start[1] <=
\ s:nrrw_rgn_lines[a:instn].start[1]
" Skip this instn
continue
else
let s:nrrw_rgn_lines[instn].start[1] += a:adjust
let s:nrrw_rgn_lines[instn].end[1] += a:adjust
if s:nrrw_rgn_lines[instn].start[1] < 1
let s:nrrw_rgn_lines[instn].start[1] = 1
endif
if s:nrrw_rgn_lines[instn].end[1] < 1
let s:nrrw_rgn_lines[instn].end[1] = 1
endif
call <sid>DeleteMatches(instn)
call <sid>AddMatches(<sid>GeneratePattern(
\s:nrrw_rgn_lines[instn].start[1:2],
\s:nrrw_rgn_lines[instn].end[1:2],
\'V'), instn)
endif
endfor
endfun
fun! <sid>NrrwSettings(on) abort "{{{1
if a:on
setl noswapfile buftype=acwrite foldcolumn=0
setl nobuflisted
let instn = matchstr(bufname(''), '_\zs\d\+$')+0
if has_key(s:nrrw_rgn_lines, s:instn)
if !&hidden && !has_key(s:nrrw_rgn_lines[instn], "single")
setl bufhidden=wipe
else
setl bufhidden=delete
endif
endif
else
setl swapfile buftype= bufhidden= buflisted
endif
endfun
fun! <sid>SetupBufLocalCommands() abort "{{{1
com! -buffer -bang WidenRegion :call nrrwrgn#WidenRegion(<bang>0)
com! -buffer NRSyncOnWrite :call nrrwrgn#ToggleSyncWrite(1)
com! -buffer NRNoSyncOnWrite :call nrrwrgn#ToggleSyncWrite(0)
endfun
fun! <sid>SetupBufLocalMaps(bang) abort "{{{1
if !hasmapto('<Plug>NrrwrgnWinIncr', 'n')
nmap <buffer> <Leader><Space> <Plug>NrrwrgnWinIncr
endif
if !hasmapto('NrrwRgnIncr')
nmap <buffer><unique> <Plug>NrrwrgnWinIncr NrrwRgnIncr
endif
nnoremap <buffer><silent><script><expr> NrrwRgnIncr <sid>ToggleWindowSize()
if a:bang && winnr('$') == 1
" Map away :q and :q! in single window mode, so that :q won't
" accidently quit vim.
cabbr <buffer> q <c-r>=(getcmdtype()==':'&&getcmdpos()==1 ? ':bd' : ':q')<cr>
cabbr <buffer> q! <c-r>=(getcmdtype()==':'&&getcmdpos()==1 ? ':bd!' : ':q!')<cr>
endif
endfun
fun! <sid>NrrwDivNear(n, d) abort "{{{1
let m = a:n % a:d
let q = a:n / a:d
let r = m*2 >= a:d ? 1 : 0
return q + r
endfun
fun! <sid>NrrwDivCeil(n, d) abort "{{{1
let q = a:n / a:d
let r = q*a:d == a:n ? 0 : 1
return q + r
endfun
fun! <sid>IsAbsPos(pos) abort "{{{1
if s:syntax
return a:pos =~ '^\%(to\%[pleft]\|bo\%[tright]\)$'
else
return len(a:pos) >= 2 && ('topleft' =~ '^' . a:pos || 'botright' =~ '^' . a:pos)
endif
endfun
fun! <sid>GetTotalSizesFromID(id) abort "{{{1
let sizes = [0,0]
let l:count = 0
for window in range(1, winnr('$'))
let nrrw_rgn_id = getwinvar(window, 'nrrw_rgn_id', 0)
if nrrw_rgn_id == a:id
let sizes[0] += winwidth(window)
let sizes[1] += winheight(window)
let l:count += 1
endif
endfor
if l:count < 1 || l:count > 2
throw "Invalid NrrwRgn window ID count of '" . l:count . "'"
endif
return sizes
endfun
fun! <sid>GetTotalSizes(window) abort "{{{1
let nrrw_rgn_id = getwinvar(a:window, 'nrrw_rgn_id', 0)
if nrrw_rgn_id > 0
return <sid>GetTotalSizesFromID(nrrw_rgn_id)
else
throw "Expected NrrwRgn window ID"
endif
endfun
fun! <sid>GetRelVSizes(window, lines) abort "{{{1
if <sid>IsAbsPos(get(g:, 'nrrw_topbot_leftright', ''))
let lines_parent = &lines
else
let lines_parent = <sid>GetTotalSizes(a:window)[1]
endif
if s:float
let nrrw_rgn_rel_max = get(g:, 'nrrw_rgn_rel_max', 80)/100.0
let nrrw_rgn_rel_min = get(g:, 'nrrw_rgn_rel_min', 10)/100.0
let ratio = 1.0*a:lines/lines_parent
if ratio < nrrw_rgn_rel_min
let ratio = nrrw_rgn_rel_min
elseif ratio > nrrw_rgn_rel_max
let ratio = nrrw_rgn_rel_max
endif
let size_max = min([lines_parent, float2nr(ceil(nrrw_rgn_rel_max*lines_parent))])
let size_min = min([lines_parent, float2nr(ceil(nrrw_rgn_rel_min*lines_parent))])
let size_tgt = min([lines_parent, float2nr(ceil(ratio*lines_parent))])
else
let nrrw_rgn_rel_max = get(g:, 'nrrw_rgn_rel_max', 80)
let nrrw_rgn_rel_min = get(g:, 'nrrw_rgn_rel_min', 10)
let percentage = <sid>NrrwDivNear(a:lines*100, lines_parent)
if percentage < nrrw_rgn_rel_min
let percentage = nrrw_rgn_rel_min
elseif percentage > nrrw_rgn_rel_max
let percentage = nrrw_rgn_rel_max
endif
let size_max = min([lines_parent, <sid>NrrwDivCeil(nrrw_rgn_rel_max*lines_parent, 100)])
let size_min = min([lines_parent, <sid>NrrwDivCeil(nrrw_rgn_rel_min*lines_parent, 100)])
let size_tgt = min([lines_parent, <sid>NrrwDivCeil(percentage*lines_parent, 100)])
endif
let size_alt = (size_tgt >= size_max ? size_min : size_max)
return [size_tgt, size_alt]
endfun
fun! <sid>GetRelHSizes(window) abort "{{{1
if <sid>IsAbsPos(get(g:, 'nrrw_topbot_leftright', ''))
let columns_parent = &columns
else
let columns_parent = <sid>GetTotalSizes(a:window)[0]
endif
let nrrw_rgn_rel_max = get(g:, 'nrrw_rgn_rel_max', 80)
let nrrw_rgn_rel_min = get(g:, 'nrrw_rgn_rel_min', 50)
if s:float
let size_max = min([columns_parent, float2nr(ceil(nrrw_rgn_rel_max/100.0*columns_parent))])
let size_min = min([columns_parent, float2nr(ceil(nrrw_rgn_rel_min/100.0*columns_parent))])
else
let size_max = min([columns_parent, <sid>NrrwDivCeil(nrrw_rgn_rel_max*columns_parent, 100)])
let size_min = min([columns_parent, <sid>NrrwDivCeil(nrrw_rgn_rel_min*columns_parent, 100))])
endif
return [size_min, size_max]
endfun
fun! <sid>GetRelSizes(window, lines) abort "{{{1
return (s:nrrw_rgn_vert ? <sid>GetRelHSizes(a:window) : <sid>GetRelVSizes(a:window, a:lines))
endfun
fun! <sid>GetAbsVSizes(window, lines) abort "{{{1
let nrrw_rgn_incr = get(g:, 'nrrw_rgn_incr', 10)
if s:nrrw_rgn_wdth > 0
let size_min = min([s:nrrw_rgn_wdth, a:lines])
else
let size_min = winheight(a:window)
endif
let size_max = size_min + nrrw_rgn_incr
return [size_min, size_max]
endfun
fun! <sid>GetAbsHSizes(window) abort "{{{1
let nrrw_rgn_incr = get(g:, 'nrrw_rgn_incr', 10)
if s:nrrw_rgn_wdth > 0
let size_min = s:nrrw_rgn_wdth
else
let size_min = winwidth(a:window)
endif
let size_max = size_min + nrrw_rgn_incr
return [size_min, size_max]
endfun
fun! <sid>GetAbsSizes(window, lines) abort "{{{1
return (s:nrrw_rgn_vert ? <sid>GetAbsHSizes(a:window) : <sid>GetAbsVSizes(a:window, a:lines))
endfun
fun! <sid>GetSizes(window, lines) abort "{{{1
let nrrw_rgn_absolute = get(g:, 'nrrw_rgn_resize_window', 'absolute') is? "absolute" ? 1 : 0
return (nrrw_rgn_absolute ? <sid>GetAbsSizes(a:window, a:lines) : <sid>GetRelSizes(a:window, a:lines))
endfun
fun! <sid>ResizeWindow(size) abort "{{{1
let prefix = (s:nrrw_rgn_vert ? ':vert ': ''). ':resize'
let cmd = printf("%s %d", prefix, a:size)
return cmd
endfu
fun! <sid>ToggleWindowSize() abort "{{{1
" Should only be called from the narrowed window!
" assumes a narrowed window is currently focused
if has_key(s:nrrw_rgn_lines[b:nrrw_instn], 'single') && s:nrrw_rgn_lines[b:nrrw_instn].single
call <sid>WarningMsg("Resizing window for single windows not supported!")
return ''
endif
let nrrw_rgn_pad = get(g:, 'nrrw_rgn_pad', 0)
let [size_tgt, size_alt] = <sid>GetSizes(winnr(), line('$') + nrrw_rgn_pad)
let size_cur = (s:nrrw_rgn_vert ? winwidth(0) : winheight(0))
let size_new = (size_cur == size_tgt ? size_alt : size_tgt)
return <sid>ResizeWindow(size_new)."\n"
endfun
fun! <sid>AdjustWindowSize(bang) abort "{{{1
" initial window sizes
" assumes a narrowed window is currently focused
if !a:bang
let nrrw_rgn_pad = get(g:, 'nrrw_rgn_pad', 0)
let size_new = <sid>GetSizes(winnr(), line('$') + nrrw_rgn_pad)[0]
exe <sid>ResizeWindow(size_new)
endif
endfun
fun! <sid>ReturnComments() abort "{{{1
let cmt = <sid>ReturnCommentFT()
let c_s = split(cmt)[0]
let c_e = (len(split(cmt)) == 1 ? "" : " ". split(cmt)[1])
return [c_s, c_e]
endfun
fun! nrrwrgn#NrrwRgnDoMulti(...) abort "{{{1
let bang = (a:0 > 0 && !empty(a:1))
if !exists("s:nrrw_rgn_line")
call <sid>WarningMsg("You need to first select the lines to".
\ " narrow using :NRP!")
return
endif
if empty(s:nrrw_rgn_line) && !exists("s:nrrw_rgn_buf")
call <sid>WarningMsg("No lines selected from :NRP, aborting!")
return
endif
if !exists("s:nrrw_rgn_buf")
let s:nrrw_rgn_buf = <sid>ParseList(s:nrrw_rgn_line)
endif
if empty(s:nrrw_rgn_buf)
call <sid>WarningMsg("An error occured when selecting all lines. Please report as bug")
unlet s:nrrw_rgn_buf
return
endif
let o_lz = &lz
set lz
let orig_buf=bufnr('')
" initialize Variables
call <sid>Init()
call <sid>CheckProtected()
let s:nrrw_rgn_lines[s:instn].start = []
let s:nrrw_rgn_lines[s:instn].end = []
let s:nrrw_rgn_lines[s:instn].multi = s:nrrw_rgn_buf
let s:nrrw_rgn_lines[s:instn].orig_buf = orig_buf
call <sid>DeleteMatches(s:instn)
let nr=0
let lines=[]
let buffer=[]
for buf in sort(keys(s:nrrw_rgn_buf), (s:numeric_sort ? 'n' : "<sid>CompareNumbers"))
if buf !=? bufnr('%')
exe ":noa " . buf. "b"
endif
let keys = keys(s:nrrw_rgn_buf[buf])
call sort(keys, (s:numeric_sort ? 'n' : "<sid>CompareNumbers"))
"for [ nr,lines] in items(s:nrrw_rgn_buf)
let [c_s, c_e] = <sid>ReturnComments()
for nr in keys
let lines = s:nrrw_rgn_buf[buf][nr]
let start = lines[0]
let end = len(lines)==2 ? lines[1] : lines[0]
if !bang
call <sid>AddMatches(<sid>GeneratePattern([start,0],
\ [end,0], 'V'), s:instn)
endif
call add(buffer, c_s.' Start NrrwRgn'.nr.' buffer: '.simplify(bufname("")).c_e)
let buffer = buffer +
\ getline(start,end) +
\ [c_s.' End NrrwRgn'.nr. ' buffer: '.
\ simplify(bufname("")).c_e, '']
endfor
endfor
if bufnr('') !=# orig_buf
" switch back to buffer, where we started
exe ":noa ". orig_buf. "b"
endif
let local_options = <sid>GetOptions(s:opts)
let win=<sid>NrrwRgnWin(bang)
if bang
let s:nrrw_rgn_lines[s:instn].single = 1
endif
let b:orig_buf = orig_buf
call setline(1, buffer)
call <sid>AdjustWindowSize(bang)
setl nomod
let b:nrrw_instn = s:instn
call <sid>SetupBufLocalCommands()
call <sid>SetupBufLocalMaps(bang)
call <sid>NrrwRgnAuCmd(0)
call <sid>SetOptions(local_options)
call <sid>CleanRegions()
call <sid>HideNrrwRgnLines()
" restore settings
let &lz = o_lz
endfun
fun! nrrwrgn#NrrwRgn(mode, ...) range abort "{{{1
let visual = !empty(a:mode)
" a:mode is set when using visual mode
if visual
" This beeps, when called from command mode
" e.g. by using :NRV, so using :sil!
" else exiting visual mode
if s:getcurpos && a:mode ==# ''
" This is an ugly hack, since there does not seem to be a
" possibility to find out, if we are in block-wise '$' mode or
" not (try pressing '$' in block-wise mode)
if !hasmapto('let s:curswant', 'v')
xmap <expr> <Plug>NrrwrgnGetCurswant ":\<c-u>let s:curswant=".getcurpos()[4]."\n"
endif
" Reselect visual mode
exe ":norm gv\<Plug>NrrwrgnGetCurswant"
else
exe "sil! norm! \<ESC>"
endif
endif
let bang = (a:0 > 0 && !empty(a:1))
let o_lz = &lz
set lz
call <sid>Init()
if visual
let s:nrrw_rgn_lines[s:instn].vmode=a:mode
endif
" Protect the original buffer,
" so you won't accidentally modify those lines,
" that will later be overwritten
let orig_buf=bufnr('')
let _opts = <sid>SaveRestoreRegister([])
call <sid>CheckProtected()
if visual
let [ s:nrrw_rgn_lines[s:instn].start,
\ s:nrrw_rgn_lines[s:instn].end ] = <sid>RetVisRegionPos()
norm! gv"ay
if len(split(@a, "\n", 1)) !=
\ (s:nrrw_rgn_lines[s:instn].end[1] -
\ s:nrrw_rgn_lines[s:instn].start[1] + 1)
" remove trailing "\n"
let @a=substitute(@a, '\n$', '', '')
endif
let a = split(@a, "\n")
else
let first = a:firstline
let last = a:lastline
let s:nrrw_rgn_lines[s:instn].start = [ 0, first, 0, 0 ]
let s:nrrw_rgn_lines[s:instn].end = [ 0, last , 0, 0 ]
let a=getline(s:nrrw_rgn_lines[s:instn].start[1],
\ s:nrrw_rgn_lines[s:instn].end[1])
endif
call <sid>DeleteMatches(s:instn)
let local_options = <sid>GetOptions(s:opts)
let win=<sid>NrrwRgnWin(bang)
if bang
let s:nrrw_rgn_lines[s:instn].single = 1
else
" Set the highlighting
noa wincmd p
" Set highlighting in original window
call <sid>AddMatches(<sid>GeneratePattern(
\s:nrrw_rgn_lines[s:instn].start[1:2],
\s:nrrw_rgn_lines[s:instn].end[1:2],
\(visual ? s:nrrw_rgn_lines[s:instn].vmode : 'V')),
\s:instn)
if _opts[1][0]
" reset folding
setl foldenable
let &l:fdm=_opts[1][1]
endif
" move back to narrowed window
noa wincmd p
endif
let b:orig_buf = orig_buf
let s:nrrw_rgn_lines[s:instn].orig_buf = orig_buf
call setline(1, a)
call <sid>AdjustWindowSize(bang)
let b:nrrw_instn = s:instn
setl nomod
call <sid>SetupBufLocalCommands()
call <sid>SetupBufLocalMaps(bang)
call <sid>NrrwRgnAuCmd(0)
call <sid>SetOptions(local_options)
if has_key(s:nrrw_aucmd, "create")
exe s:nrrw_aucmd["create"]
endif
if has_key(s:nrrw_aucmd, "close")
let b:nrrw_aucmd_close = s:nrrw_aucmd["close"]
endif
call <sid>SaveRestoreRegister(_opts)
" restore settings
let &lz = o_lz
endfun
fun! nrrwrgn#Prepare(bang) abort "{{{1
if !exists("s:nrrw_rgn_line") || !empty(a:bang)
let s:nrrw_rgn_line={}
if !empty(a:bang)
return
endif
endif
if !has_key(s:nrrw_rgn_line, bufnr('%'))
let s:nrrw_rgn_line[bufnr('%')] = []
endif
call add(s:nrrw_rgn_line[bufnr('%')], line('.'))
endfun
fun! nrrwrgn#WidenRegion(force) abort "{{{1
" a:force: original narrowed window is going to be closed
" so, clean up, don't renew highlighting, etc.
let nrw_buf = bufnr('')
let orig_buf = b:orig_buf
let orig_tab = tabpagenr()
let instn = b:nrrw_instn
" Make sure the narrowed buffer is still valid (happens, when 2 split
" window of the narrowed buffer is opened.
if !has_key(s:nrrw_rgn_lines, instn)
call <sid>WarningMsg("Error writing changes back,".
\ "Narrowed Window invalid!")
return
endif
let winnr = winnr()
let close = has_key(s:nrrw_rgn_lines[instn], 'single')
let vmode = has_key(s:nrrw_rgn_lines[instn], 'vmode')
" Save current state
let nr = changenr()
" Execute autocommands
if has_key(s:nrrw_aucmd, "close")
exe s:nrrw_aucmd["close"]
endif
let cont = getline(1,'$')
if has_key(s:nrrw_aucmd, "close") && nr != changenr()
" Restore buffer contents before the autocommand
" (in case the window isn't closed, the user sees
" the correct input)
exe "undo" nr
endif
if !has_key(s:nrrw_rgn_lines[instn], 'multi')
" <sid>WidenRegionMulti does take care of loading the correct buffer!
call <sid>JumpToBufinTab(<sid>BufInTab(orig_buf), orig_buf, instn, s:window_type["source"])
let orig_win = bufwinnr(orig_buf)
" Should be in the right tab now!
if (orig_win == -1)
if bufexists(orig_buf)
" buffer not in current window, switch to it!
exe "noa" orig_buf "b!"
" Make sure highlighting will be removed
let close = (&g:hid ? 0 : 1)
else
call s:WarningMsg("Original buffer does no longer exist! Aborting!")
return
endif
else
exe ':noa'. orig_win. 'wincmd w'
endif
" Removing matches only works in the right window. So need to check,
" the matchid actually exists, if not, try to remove it later.
if <sid>HasMatchID(instn)
call <sid>DeleteMatches(instn)
endif
if exists("b:orig_buf_ro") && b:orig_buf_ro && !a:force
call s:WarningMsg("Original buffer protected. Can't write changes!")
call <sid>JumpToBufinTab(orig_tab, nrw_buf, instn, s:window_type["target"])
return
endif
if !&l:ma && !(exists("b:orig_buf_ro") && b:orig_buf_ro)
setl ma
endif
endif
let _opts = <sid>SaveRestoreRegister([])
let wsv=winsaveview()
" This is needed to adjust all other narrowed regions
" in case we have several narrowed regions within the same buffer
if exists("g:nrrw_rgn_protect") && g:nrrw_rgn_protect =~? 'n'
let adjust_line_numbers = len(cont) - 1 - (
\s:nrrw_rgn_lines[instn].end[1] -
\s:nrrw_rgn_lines[instn].start[1])
endif
" Now copy the content back into the original buffer
" 1) Check: Multiselection
if has_key(s:nrrw_rgn_lines[instn], 'multi')
call <sid>WidenRegionMulti(cont, instn)
" 2) Visual Selection
elseif vmode
"charwise, linewise or blockwise selection
call setreg('a', join(cont, "\n"). "\n",
\ s:nrrw_rgn_lines[instn].vmode)
if s:nrrw_rgn_lines[instn].vmode == 'v' &&
\ s:nrrw_rgn_lines[instn].end[1] -
\ s:nrrw_rgn_lines[instn].start[1] + 1 == len(cont)
" in characterwise selection, remove trailing \n
call setreg('a', substitute(@a, '\n$', '', ''), 'v')
endif
" settable '< and '> marks
let _v = []
" store actual values
let _v = [getpos("'<"), getpos("'>"), [visualmode(1)]]
" set the mode for the gv command
exe "norm! ". s:nrrw_rgn_lines[instn].vmode."\<ESC>"
call setpos("'<", s:nrrw_rgn_lines[instn].start)
call setpos("'>", s:nrrw_rgn_lines[instn].end)
exe 'norm! gv"aP'
if !empty(_v[2][0]) && (_v[2][0] != visualmode())
exe 'norm!' _v[2][0]. "\<ESC>"
call setpos("'<", _v[0])
call setpos("'>", _v[1])
endif
" Recalculate the start and end positions of the narrowed window
" so subsequent calls will adjust the region accordingly
let [ s:nrrw_rgn_lines[instn].start,
\s:nrrw_rgn_lines[instn].end ] = <sid>RetVisRegionPos()
" make sure the visual selected lines did not add a new linebreak,
" this messes up the characterwise selected regions and removes lines
" on further writings
if s:nrrw_rgn_lines[instn].end[1] - s:nrrw_rgn_lines[instn].start[1]
\ + 1 > len(cont) && s:nrrw_rgn_lines[instn].vmode == 'v'
let s:nrrw_rgn_lines[instn].end[1] =
\ s:nrrw_rgn_lines[instn].end[1] - 1
let s:nrrw_rgn_lines[instn].end[2] = virtcol('$')
endif
" also, renew the highlighted region
" only highlight, if we are in a different window
" then where we started, else we might accidentally
" set a match in the narrowed window (might happen if the
" user typed Ctrl-W o in the narrowed window)
if !(has_key(s:nrrw_rgn_lines[instn], 'single') || winnr != winnr())
call <sid>AddMatches(<sid>GeneratePattern(
\ s:nrrw_rgn_lines[instn].start[1:2],
\ s:nrrw_rgn_lines[instn].end[1:2],
\ s:nrrw_rgn_lines[instn].vmode),
\ instn)
endif
" 3) :NR started selection
else
" linewise selection because we started the NarrowRegion with the
" command NarrowRegion(0)
"
" if the endposition of the narrowed buffer is also the last line of
" the buffer, the append will add an extra newline that needs to be
" cleared.
if s:nrrw_rgn_lines[instn].end[1]==line('$') &&
\ s:nrrw_rgn_lines[instn].start[1] == 1
let delete_last_line=1
else
let delete_last_line=0
endif
exe ':silent :'.s:nrrw_rgn_lines[instn].start[1].','
\.s:nrrw_rgn_lines[instn].end[1].'d _'
call append((s:nrrw_rgn_lines[instn].start[1]-1),cont)
" Recalculate the start and end positions of the narrowed window
" so subsequent calls will adjust the region accordingly
" so subsequent calls will adjust the region accordingly
let s:nrrw_rgn_lines[instn].end[1] =
\ s:nrrw_rgn_lines[instn].start[1] + len(cont) -1
if s:nrrw_rgn_lines[instn].end[1] > line('$')
let s:nrrw_rgn_lines[instn].end[1] = line('$')
endif
" only highlight, if we are in a different window
" then where we started, else we might accidentally
" set a match in the narrowed window (might happen if the
" user typed Ctrl-W o in the narrowed window)
if !(has_key(s:nrrw_rgn_lines[instn], 'single') || winnr != winnr())
call <sid>AddMatches(<sid>GeneratePattern(
\s:nrrw_rgn_lines[instn].start[1:2],
\s:nrrw_rgn_lines[instn].end[1:2],
\'V'),
\instn)
endif
if delete_last_line
silent! $d _
endif
endif
" Recalculate start- and endline numbers for all other Narrowed Windows.
" This matters, if you narrow different regions of the same file and
" write your changes back.
if exists("g:nrrw_rgn_protect") && g:nrrw_rgn_protect =~? 'n'
call <sid>RecalculateLineNumbers(instn, adjust_line_numbers)
endif
" if close && !has_key(s:nrrw_rgn_lines[instn], 'single')
" For narrowed windows that have been created using !,
" don't clean up yet, or else we loose all data and can't write
" it back later.
" (e.g. :NR! createas a new single window, do :sp
" and you can only write one of the windows back, the other will
" become invalid, if CleanUp is executed)
" endif
call <sid>SaveRestoreRegister(_opts)
" Execute "written" autocommands in the original buffer
if exists("b:nrrw_aucmd_written")
exe b:nrrw_aucmd_written
endif
call winrestview(wsv)
"if !close && has_key(s:nrrw_rgn_lines[instn], 'single')
if has_key(s:nrrw_rgn_lines[instn], 'single')
" move back to narrowed buffer
noa b #
"elseif close
" call <sid>CleanUpInstn(instn)
endif
let bufnr = bufnr('')
" jump back to narrowed window
call <sid>JumpToBufinTab(orig_tab, nrw_buf, instn, s:window_type["target"])
if bufnr('') != bufnr
" do not set the original buffer unmodified
setl nomod
endif
if a:force
" trigger auto command
bw
endif
endfun
fun! nrrwrgn#UnifiedDiff() abort "{{{1
let save_winposview=winsaveview()
let orig_win = winnr()
" close previous opened Narrowed buffers
silent! windo | if bufname('')=~'^NrrwRgn' &&
\ &diff |diffoff|q!|endif
" minimize Window
" this is disabled, because this might be useful, to see everything
"exe "vert resize -999999"
"setl winfixwidth
" move to current start of chunk of unified diff
if search('^@@', 'bcW') > 0
call search('^@@', 'bc')
else
call search('^@@', 'c')
endif
let curpos=getpos('.')
for i in range(2)
if search('^@@', 'nW') > 0
.+,/@@/-NR
else
" Last chunk in file
.+,$NR
endif
" Split vertically
noa wincmd H
if i==0
silent! g/^-/d _
else
silent! g/^+/d _
endif
diffthis
0
exe ":noa wincmd p"
call setpos('.', curpos)
endfor
call winrestview(save_winposview)
endfun
fun! nrrwrgn#ToggleSyncWrite(enable) abort "{{{1
let s:nrrw_rgn_lines[b:nrrw_instn].disable = !a:enable
" Enable syncing of bufers
if a:enable
" Enable Narrow settings and autocommands
call <sid>NrrwSettings(1)
call <sid>NrrwRgnAuCmd(0)
setl modified
else
" Disable Narrow settings and autocommands
call <sid>NrrwSettings(0)
" b:nrrw_instn should always be available
call <sid>NrrwRgnAuCmd(b:nrrw_instn)
endif
endfun
fun! nrrwrgn#LastNrrwRgn(bang) abort "{{{1
let bang = !empty(a:bang)
if !exists("s:nrrw_rgn_lines") || !has_key(s:nrrw_rgn_lines, 'last')
call <sid>WarningMsg("There is no last region to re-select")
return
endif
let orig_buf = s:nrrw_rgn_lines['last'][0][0] + 0
let tab = <sid>BufInTab(orig_buf)
if tab != tabpagenr() && tab > 0
exe "tabn" tab
endif
let orig_win = bufwinnr(orig_buf)
" Should be in the right tab now!
if (orig_win == -1)
call s:WarningMsg("Original buffer does no longer exist! Aborting!")
return
endif
if orig_win != winnr()
exe "noa" orig_win "wincmd w"
endif
if len(s:nrrw_rgn_lines['last']) == 1
" Multi Narrowed
let s:nrrw_rgn_buf = s:nrrw_rgn_lines['last'][0][1]
call nrrwrgn#NrrwRgnDoMulti('')
else
exe "keepj" s:nrrw_rgn_lines['last'][0][1][0]
exe "keepj norm!" s:nrrw_rgn_lines['last'][0][1][1]. '|'
" Start visual mode
exe "keepj norm!" s:nrrw_rgn_lines['last'][2]
exe "keepj" s:nrrw_rgn_lines['last'][1][1][0]
if col(s:nrrw_rgn_lines['last'][1][1][1]) == col('$') &&
\ s:nrrw_rgn_lines['last'][2] == ''
" Best guess
exe "keepj $"
else
exe "keepj norm!" s:nrrw_rgn_lines['last'][1][1][1]. '|'
endif
" Call VisualNrrwRgn()
call nrrwrgn#NrrwRgn(visualmode(), bang)
endif
endfu
fun! nrrwrgn#NrrwRgnStatus() abort "{{{1
if !exists("b:nrrw_instn")
return {}
else
let dict={}
try
let cur = deepcopy(s:nrrw_rgn_lines[b:nrrw_instn])
if has_key(cur, 'multi')
let multi = cur.multi
else
let multi = []
endif
let dict.shortname = bufname('')
let bufname=bufname(cur.orig_buf)
if !empty(bufname)
let dict.fullname = fnamemodify(expand(bufname(cur.orig_buf)),':p')
else
let dict.fullname = '[No Name]' " vim default
endif
let dict.multi = has_key(cur, 'multi')
if has_key(cur, 'multi')
let end = keys(multi[1])[-1]
let dict.startl= map(copy(multi), 'v:val[1][0]')
let dict.endl = map(copy(multi), 'v:val[end][1]')
else
let dict.start = cur.start
let dict.end = cur.end
endif
let dict.matchid = cur.matchid
let dict.visual = has_key(cur, 'vmode') ? cur.vmode : ''
let dict.enabled = has_key(cur, 'disable') ? (cur.disable ? 0 : 1) : 1
let dict.instn = b:nrrw_instn
unlet cur
catch
" oh oh, something is wrong...
let dict={}
endtry
lockvar dict
return dict
endif
endfu
" Debugging options "{{{1
fun! nrrwrgn#Debug(enable) abort "{{{2
if (a:enable)
let s:debug=1
fun! <sid>NrrwRgnDebug() abort "{{{2
"sil! unlet s:instn
com! NI :call <sid>WarningMsg("Instance: ".s:instn)
com! NJ :call <sid>WarningMsg("Data: ".string(s:nrrw_rgn_lines))
com! -nargs=1 NOutput :if exists("s:".<q-args>)|redraw!|
\ :exe 'echo s:'.<q-args>|else|
\ echo "s:".<q-args>. " does not exist!"|endif
endfun
call <sid>NrrwRgnDebug()
else
let s:debug=0
delf <sid>NrrwRgnDebug
delc NI
delc NJ
delc NOutput
endif
endfun
" Modeline {{{1
" vim: noet ts=4 sts=4 fdm=marker com+=l\:\" fdl=0
doc/NarrowRegion.txt [[[1
792
*NrrwRgn.txt* A Narrow Region Plugin (similar to Emacs)
Author: Christian Brabandt <cb@256bit.org>
Version: 0.33 Thu, 15 Jan 2015 20:52:29 +0100
Copyright: (c) 2009-2015 by Christian Brabandt
The VIM LICENSE applies to NrrwRgnPlugin.vim and NrrwRgnPlugin.txt
(see |copyright|) except use NrrwRgnPlugin instead of "Vim".
NO WARRANTY, EXPRESS OR IMPLIED. USE AT-YOUR-OWN-RISK.
==============================================================================
1. Contents *NarrowRegion* *NrrwRgnPlugin*
1. Contents.....................................: |NrrwRgnPlugin|
2. NrrwRgn Manual...............................: |NrrwRgn-manual|
2.1 NrrwRgn Howto..............................: |NR-HowTo|
2.2 NrrwRgn Multi..............................: |NR-multi-example|
2.3 NrrwRgn Configuration......................: |NrrwRgn-config|
2.4 NrrwRgn public functions...................: |NrrwRgn-func|
3. NrrwRgn Tips.................................: |NrrwRgn-tips|
4. NrrwRgn Feedback.............................: |NrrwRgn-feedback|
5. NrrwRgn History..............................: |NrrwRgn-history|
==============================================================================
2. NrrwRgn Manual *NrrwRgn-manual*
Functionality
This plugin is based on a discussion in comp.editors (see the thread at
http://groups.google.com/group/comp.editors/browse_frm/thread/0f562d97f80dde13)
Narrowing means focussing on a region and making the rest inaccessible. You
simply select the region, call |:NarrowRegion| and the selected part will open
in a new scratch buffer. The rest of the file will be protected, so you won't
accidentally modify that buffer. In the new buffer, you can do a global
replace, search or anything else to modify that part. When you are finished,
simply write that buffer (e.g. by |:w|) and your modifications will be put in
the original buffer making it accessible again. Use |:q!| or |:bw!| to abort
your changes and return back to the original window.
NrrwRgn allows you to either select a line based selection using an Ex-command
or you can simply use any visual selected region and press your preferred key
combination to open that selection in a new buffer.
This plugin defines the following commands:
*:NarrowRegion* *:NR*
:[range]NR[!]
:[range]NarrowRegion[!] When [range] is omitted, select only the current
line, else use the lines in the range given and
open it in a new Scratch Window.
If the current line is selected and is on a folded
region, select the whole folded text.
Whenever you are finished modifying that region
simply write the buffer.
If ! is given, open the narrowed buffer not in a
split buffer but in the current window.
*:NarrowWindow* *:NW*
:NW[!]
:NarrowWindow[!] Select only the range that is visible the current
window and open it in a new Scratch Window.
Whenever you are finished modifying that region
simply write the buffer.
If ! is given, open the narrowed buffer not in a
split buffer but in the current window (works best
with 'hidden' set).
*:WidenRegion*
:WidenRegion[!] This command is only available in the narrowed
scratch window. If the buffer has been modified,
the contents will be put back on the original
buffer. If ! is specified, the window will be
closed, otherwise it will remain open.
*:NRV*
:NRV[!] Opened the narrowed window for the region that was
last selected in visual mode
If ! is given, open the narrowed buffer not in a
split buffer but in the current window (works best
with 'hidden' set).
*:NUD*
:NUD When viewing unified diffs, this command opens
the current chunk in 2 Narrowed Windows in
|diff-mode| The current chunk is determined as the
one, that the cursor is at. This command does not
make sense if editing a different file format (or
even different diff format)
*:NRPrepare*
:[range]NRPrepare[!]
:[range]NRP[!] You can use this command, to mark several lines
that will later be put into a Narrowed Window
using |:NRM|.
If the ! is used, all earlier selected lines will
be cleared first.
*:NRMulti*
:NRMulti
:NRM[!] This command takes all lines, that have been
marked by |:NRP| and puts them together in a new
narrowed buffer.
When you write your changes back, all separate
lines will be put back at their origin.
This command also clears the list of marked lines,
that was created with |NRP|.
See also |NR-multi-example|.
If ! is given, open the narrowed buffer not in a
split buffer but in the current window (works best
with 'hidden' set).
*:NRSyncOnWrite* *:NRS*
:NRSyncOnWrite
:NRS Enable synching the buffer content back to the
original buffer when writing.
(this is the default).
*:NRNoSyncOnWrite* *:NRN*
:NRNoSyncOnWrite
:NRN Disable synching the buffer content back to the
original buffer when writing. When set, the
narrowed buffer behaves like an ordinary buffer
that you can write in the filesystem.
(this is the default).
Note: You can still use |:WidenRegion| to write
the changes back to the original buffer.
*:NRL*
:NRL[!] Reselect the last selected region again and open
in a narrowed window.
If ! is given, open the narrowed buffer not in a
split buffer but in the current window (works best
with 'hidden' set).
2.1 NrrwRgn HowTo *NR-HowTo*
-----------------
Use the commands provided above to select a certain region to narrow. You can
also start visual mode and have the selected region being narrowed. In this
mode, NarrowRegion allows you to block select |CTRL-V| , character select |v|
or linewise select |V| a region. Then press <Leader>nr where <Leader> by
default is set to '\', unless you have set it to something different (see
|<Leader>| for information how to change this) and the selected range will
open in a new scratch buffer. This key combination only works in |Visual-mode|
If instead of <Leader>nr you use <Leader>Nr in visual mode, the selection will
be opened in the current window, replacing the original buffer.
(Alternatively, you can use the normal mode mapping <Leader>nr and the region
over which you move will be opened in a new Narrowed window).
When finished, simply write that Narrowed Region window, from which you want
to take the modifications in your original file.
It is possible, to recursively open a Narrowed Window on top of an already
narrowed window. This sounds a little bit silly, but this makes it possible,
to have several narrowed windows, which you can use for several different
things, e.g. If you have 2 different buffers opened and you want to diff a
certain region of each of those 2 buffers, simply open a Narrowed Window for
each buffer, and execute |:diffthis| in each narrowed window.
You can then interactively merge those 2 windows. And when you are finished,
simply write the narrowed window and the changes will be taken back into the
original buffer.
When viewing unified diffs, you can use the provided |:NUD| command to open 2
Narrowed Windows side by side viewing the current chunk in |diff-mode|. Those
2 Narrowed windows will be marked 'modified', since there was some post
processing involved when opening the narrowed windows. Be careful, when
quitting the windows, not to write unwanted changes into your patch file! In
the window that contains the unified buffer, you can move to a different
chunk, run |:NUD| and the 2 Narrowed Windows in diff mode will update.
2.2 NrrwRgn Multi *NR-multi-example*
-----------------
Using the commands |:NRP| and |:NRM| allows to select a range of lines, that
will be put into a narrowed buffer together. This might sound confusing, but
this allows to apply a filter before making changes. For example before
editing your config file, you decide to strip all comments for making big
changes but when you write your changes back, these comments will stay in your
file. You would do it like this: >
:v/^#/NRP
:NRMulti
<
Now a Narrowed Window will open, that contains only the configuration lines.
Each block of independent region will be separated by a string like
# Start NarrowRegion1
.....
# End NarrowRegion1
This is needed, so the plugin later knows, which region belongs where in the
original place. Blocks you don't want to change, you can safely delete, they
won't be written back into your original file. But other than that, you
shouldn't change those separating lines.
When you are finished, simply write your changes back.
==============================================================================
2.3 NrrwRgn Configuration *NrrwRgn-config*
-------------------------
NarrowRegion can be customized by setting some global variables. If you'd
like to open the narrowed window as a vertical split buffer, simply set the
variable g:nrrw_rgn_vert to 1 in your |.vimrc| >
let g:nrrw_rgn_vert = 1
<
(default: 0)
------------------------------------------------------------------------------
If you'd like to specify a certain width/height for you scratch buffer, then
set the variable g:nrrw_rgn_wdth in your |.vimrc| . This variable defines the
height or the nr of columns, if you have also set g:nrrw_rgn_vert. >
let g:nrrw_rgn_wdth = 30
<
(default: 20)
Note: if the newly created narrowed window is smaller than this, it will be
resized to fit (plus an additional padding that can be specified using the
g:nrrw_rgn_pad variable (default: 0), to not leave unwanted space around (not
for single narrowed windows, e.g. when the '!' attribute was used).
------------------------------------------------------------------------------
Resizing the narrowed window can happen either by some absolute values or by a
relative percentage. The variable g:nrrw_rgn_resize_window determines what
kind of resize will occur. If it is set to "absolute", the resizing will be
done by absolute lines or columns (depending on whether a horizontal or
vertical split has been done). If it is set to "relative" the window will be
resized by a percentage. Set it like this in your |.vimrc| >
let g:nrrw_rgn_resize_window = 'absolute'
<
(default: absolute)
The percentages for increasing the window size can further be specified by
seting the following variables:
default:
g:nrrw_rgn_rel_min: 10 (50 for vertical splits)
g:nrrw_rgn_rel_max: 80
------------------------------------------------------------------------------
It is possible to specify an increment value, by which the narrowed window can
be increased. This is allows to easily toggle between the normal narrowed
window size and an even increased size (think of zooming).
You can either specify a relative or absolute zooming value. An absolute
resize will happen, if the variable g:nrrw_rgn_resize_window is set to
"absolute" or it is unset (see above).
If absolute resizing should happen you have to either specify columns, if the
Narrowed window is a vertical split window or lines, if a horizontal split has
been done.
Example, to increase the narrowed window by 30 lines or columns if
(g:nrrw_rgn_vert is also set [see above]), set in your |.vimrc| >
let g:nrrw_rgn_incr = 30
<
(default: 10, if g:nrrw_rgn_resize_window is "absolute")
Note: When using the '!' attribute for narrowing (e.g. the selection will be
opened in a new window that takes the complete screen size), no resizeing will
happen
------------------------------------------------------------------------------
If you'd like to change the key combination that toggles incrementing the
Narrowed Window size, you can put this in your |.vimrc| >
nmap <F3> <Plug>NrrwrgnWinIncr
<
(default: <Leader><Space>)
This will let you use the <F3> key to toggle the window size of the Narrowed
Window. Note: This mapping is only in the narrowed window active.
The amount of how much to increase can be further refined by setting the
g:nrrw_rgn_incr for an absolute increase of by setting the variables
g:nrrw_rgn_rel_min and g:nrrw_rgn_rel_max
Whether an absolute or relative increase will be performed, is determined by
the g:nrrw_rgn_resize_window variable (see above).
------------------------------------------------------------------------------
By default, NarrowRegion highlights the region that has been selected
using the WildMenu highlighting (see |hl-WildMenu|). If you'd like to use a
different highlighting, set the variable g:nrrw_rgn_hl to your preferred
highlighting Group. For example to have the region highlighted like a search
result, you could put that in your |.vimrc| >
let g:nrrw_rgn_hl = 'Search'
<
(default: WildMenu)
If you want to turn off the highlighting (because this can be distracting), you
can set the global variable g:nrrw_rgn_nohl to 1 in your |.vimrc| >
let g:nrrw_rgn_nohl = 1
<
(default: 0)
------------------------------------------------------------------------------
If you'd like to change the key combination that starts the Narrowed Window
for your selected range, you could put this in your |.vimrc| >
xmap <F3> <Plug>NrrwrgnDo
<
This will let <F3> open the Narrow-Window, but only if you have pressed it in
Visual Mode. It doesn't really make sense to map this combination to any other
mode, unless you want it to Narrow your last visually selected range.
(default: <Leader>nr)
------------------------------------------------------------------------------
If you'd like to specify the options that you want to have set for the
narrowed window, you can set the g:nrrw_custom_options setting, in your
|.vimrc| e.g. >
let g:nrrw_custom_options={}
let g:nrrw_custom_options['filetype'] = 'python'
>
This will only apply those options to the narrowed buffer. You need to take
care that all options you need will apply.
------------------------------------------------------------------------------
If you don't like that your narrowed window opens above the current window,
define the g:nrrw_topbot_leftright variable to your taste, e.g. >
let g:nrrw_topbot_leftright = 'botright'
<
Now, all narrowed windows will appear below the original window. If not
specified, the narrowed window will appear above/left of the original window.
(default: topleft)
------------------------------------------------------------------------------
If you want to use several independent narrowed regions of the same buffer
that you want to write at the same time, protecting the original buffer is not
really useful. Therefore, set the g:nrrw_rgn_protect variable, e.g. in your
|.vimrc| >
let g:nrrw_rgn_protect = 'n'
<
This can be useful if you diff different regions of the same file, and want
to be able to put back the changes at different positions. Please note that
you should take care not to change any part that will later be influenced
when writing the narrowed region back.
Note: Don't use overlapping regions! Your changes will probably not be put
back correctly and there is no guard against losing data accidentally. NrrwRgn
tries hard to adjust the highlighting and regions as you write your changes
back into the original buffer, but it can't guarantee that this will work and
might fail silently. Therefore, this feature is experimental!
(default: y)
------------------------------------------------------------------------------
If you are using the |:NRMulti| command and want to have the original window
update to the position of where the cursor is in the narrowed window, you can
set the variable g:nrrw_rgn_update_orig_win, e.g. in your |.vimrc| >
let g:nrrw_rgn_update_orig_win = 1
<
Now the cursor in the original window will always update when the position
changes in the narrowed window (using a |CursorMoved| autocommand).
Note: that this might slow down scrolling and cursor movement a bit.
(default: 0)
------------------------------------------------------------------------------
By default, NarrowRegion plugin defines the two mappings <Leader>nr in visual
mode and normal mode and <Leader>Nr only in visual mode. If you have your own
mappings defined, than NarrowRegion will complain about the key already being
defined. Chances are, this will be quite annoying to you, so you can disable
mappings those keys by defining the following variables in your |.vimr| >
:let g:nrrw_rgn_nomap_nr = 1
:let g:nrrw_rgn_nomap_Nr = 1
(default: 0)
----------------------------------------------------------------------------
*NrrwRgn-hook* *NR-hooks*
NarrowRegion can execute certain commands, when creating the narrowed window
and when closing the narrowed window. For this, you can set 2 buffer-local
variables that specify what commands to execute, which will hook into the
execution of the Narrow Region plugin.
For example, suppose you have a file, containing columns separated data (CSV
format) which you want to modify and you also have the CSV filetype plugin
(http://www.vim.org/scripts/script.php?script_id=2830) installed and you want
to modify the CSV data which should be visually arranged like a table in the
narrowed window.
Therefore you want the command |:ArrangeColumn| to be executed in the new
narrowed window upon entering it, and when writing the changes back, you want
the command |:UnArrangeColumn| to be executed just before putting the
changes back. So you set those two variables in your original buffer: >
let b:nrrw_aucmd_create = "set ft=csv|%ArrangeCol"
let b:nrrw_aucmd_close = "%UnArrangeColumn"
<
This will execute the commands in the narrowed window: >
:set ft=csv
:%ArrangeCol
and before writing the changes back, it'll execute: >
:%UnArrangeCol
Note: These hooks are executed in the narrowed window (i.e. after creating the
narrowed window and its content and before writing the changes back to the
original buffer).
A third hook 'b:nrrw_aucmd_written' is provided, when the data is written back
in the original window. This allows to execute scripts, whenever the data is
written back in the original window. For example, consider you want to write
the original buffer whenever the narrowed window is written back to the
original window. You can therefore set: >
:let b:nrrw_aucmd_written = ':update'
<
This will write the original buffer, whenever it was modified after writing
the changes from the narrowed window back.
2.4 NrrwRgn functions *NrrwRgn-func*
---------------------
The NrrwRgn plugin defines a public function in its namespace that can be used
to query its status.
*nrrwrgn#NrrwRgnStatus()*
nrrwrgn#NrrwRgnStatus()
Returns a dict with the following keys:
'shortname': The displayed buffer name
'fullname': The complete buffer name of the original buffer
'multi': 1 if it is a multi narrowed window (|:NRMulti|),
0 otherwise.
'startl': List of start lines for a multi narrowed window
(only present, if 'multi' is 1)
'endl': List of end lines for a multi narrowed window
(only present, if 'multi' is 1)
'start': Start position (only present if 'multi' is 0)
'end': End position (only present if 'multi' is 0)
'visual': Visual Mode, if it the narrowed window was started
from a visual selected region (empty otherwise).
'enabled': Whether syncing the buffer is enabled (|:NRS|)
If not executed in a narrowed window, returns an empty dict.
=============================================================================
3. NrrwRgn Tips *NrrwRgn-tips*
To have the filetype in the narrowed window set, you can use this function: >
command! -nargs=* -bang -range -complete=filetype NN
\ :<line1>,<line2> call nrrwrgn#NrrwRgn('',<q-bang>)
\ | set filetype=<args>
<
This lets you select a region, call :NN sql and the selected region will get
the sql filetype set.
(Contributed by @fourjay, thanks!)
=============================================================================
4. NrrwRgn Feedback *NrrwRgn-feedback*
Feedback is always welcome. If you like the plugin, please rate it at the
vim-page:
http://www.vim.org/scripts/script.php?script_id=3075
You can also follow the development of the plugin at github:
http://github.com/chrisbra/NrrwRgn
Please don't hesitate to report any bugs to the maintainer, mentioned in the
third line of this document.
If you like the plugin, write me an email (look in the third line for my mail
address). And if you are really happy, vote for the plugin and consider
looking at my Amazon whishlist: http://www.amazon.de/wishlist/2BKAHE8J7Z6UW
=============================================================================
5. NrrwRgn History *NrrwRgn-history*
0.34: (unreleased) {{{1
- merge Github Pull #34 (https://github.com/chrisbra/NrrwRgn/pull/34, by
Pyrohh, thanks!)
- resize narrowed window to actual size, this won't leave the a lot of
empty lines in the narrowed window.
- don't switch erroneously to the narrowed window on writing
(https://github.com/chrisbra/NrrwRgn/issues/35, reported by Yclept Nemo
thanks!)
- Always write the narrowed scratch window back on |:w| instead of only when
it was modified (https://github.com/chrisbra/NrrwRgn/issues/37, reported by
Konfekt, thanks!)
- Do not resize window, if :NR! was used (patch by leonidborisenko from
https://github.com/chrisbra/NrrwRgn/pull/38 thanks!)
- Various improvements for Window resizing, partly by Yclept Nemo, thanks!
- Fixed error for undefined function and cursor movement in wrong window
(issue https://github.com/chrisbra/NrrwRgn/issues/42 reported by adelarsq,
thanks!)
- Don't set the original buffer to be modified in single-window mode (issue
https://github.com/chrisbra/NrrwRgn/issues/43, reported by agguser, thanks!)
- Don't clean up on BufWinLeave autocommand, so that switching buffers will
not destroy the BufWriteCmd (issue https://github.com/chrisbra/NrrwRgn/issues/44,
reported by agguser, thanks!)
- remove highlighting after closing narrowed buffer
(also issue https://github.com/chrisbra/NrrwRgn/issues/45,
reported by Serabe, thanks!)
- do not map <Leader>nr and <Leader>Nr if g:nrrw_rgn_nomap_<key> is set
(issue https://github.com/chrisbra/NrrwRgn/issues/52, reported by
digitalronin, thanks!)
- correctly highlight in block-wise visual mode, if '$' has been pressed.
0.33: Jan 16, 2015 {{{1
- set local options later, so that FileType autocommands don't trigger to
early
- make sure, shortening the buffer name handles multibyte characters
correctly.
- new public function |nrrwrgn#NrrwRgnStatus()|
- <Leader>nr also mapped as operator function (so the region over which you
move will be opened in the narrowed window
- highlighting wrong when char-selecting within a line
- needs Vim 7.4
- mention how to abort the narrowed window (suggested by David Fishburn,
thanks!)
- Execute hooks after the options for the narrowed window have been set
(issue #29, reported by fmorales, thanks!)
- <Leader><Space> Toggles the Narrowed Window Size (idea by David Fishburn,
thanks!)
- New hook b:nrrw_aucmd_written, to be executed, whenever the narrowed info
has been written back into the original buffer.
- g:nrrw_rgn_write_on_sync is being deprecated in favor of using the newly
"written" hook
- error on writing back multi narrowed window (issue #30, reported by
aleprovencio https://github.com/chrisbra/NrrwRgn/issues/30, thanks!)
- document autoresize function (g:nrrw_rgn_autoresize_win)
- error when calling Incr Function, Make it override over global mapping.
(issue #31, reported by zc he https://github.com/chrisbra/NrrwRgn/issues/31, thanks!)
- |:NRP| didn't work as documented (reported by David Fishburn, thanks!)
- fix small syntax error in autoload file (issue #32, reported by itchyny
(https://github.com/chrisbra/NrrwRgn/issues/32, thanks!)
- check, that dict key is available before accessing it (issue #33, reported by SirCorion
(https://github.com/chrisbra/NrrwRgn/issues/33, thanks!)
0.32: Mar 27, 2014 {{{1
- hooks could corrupt the narrowed buffer, if it wasn't closed (reported by
jszakemeister https://github.com/chrisbra/NrrwRgn/issues/19, thanks!)
- Don't parse $VIMRUNTIME/doc/options.txt for finding out buffer-local options
(reported by AguirreIF https://github.com/chrisbra/NrrwRgn/issues/21,
thanks!), instead include a fix set of option names to set when opening the
narrowed buffer.
- Switching buffers in the original narrowed buffer, may confuse NrrwRgn.
- Code cleanup (no more separate functions for visual and normal mode)
- fix issue 22 (characterwise narrowing was brocken in last commit, reported
by Matthew Boehm in https://github.com/chrisbra/NrrwRgn/issues/22, thanks!)
- in characterwise visual selection, trailing \n is not stripped when writing
(reported by Matthew Boehm in https://github.com/chrisbra/NrrwRgn/23,
thanks!)
- highlighting was wrong for characterwise visual selections
- update original window for multi narrowed regions (
https://github.com/chrisbra/NrrwRgn/24, reported by Dane Summers, thanks!),
use the g:nrrw_rgn_update_orig_win variable to enable
- error when narrowed window was moved to new tab and trying to quit
(https://github.com/chrisbra/NrrwRgn/2, reported by Mario Ricalde, thanks!)
- better default names for the narrowed window
(https://github.com/chrisbra/Nrrwrgn/28, reported by Mario Ricalde, thanks!)
- when setting g:nrrw_rgn_write_on_sync the original file will be saved,
whenever the narrowed window is written back
(https://github.com/chrisbra/26, reported by Mario Ricalde, thanks!)
- Some more error handling when using |:WidenRegion|
- Make sure highlighting is removed when using |:WidenRegion|
0.31: Feb 16, 2013 {{{1
- NRM threw some errors (reported by pydave in
https://github.com/chrisbra/NrrwRgn/issues/17, thanks!)
- don't create swapfiles (reported by ping, thanks!)
0.30: Jan 25, 2013 {{{1
- |NRL| throws erros, when used without having first narrowed a region
- |NRV!| not allowed (reported by ping, thanks!)
- when using single window narrowing, :w would jump back to the original
window. Only do this, when 'hidden' is not set (reported by ping, thanks!)
- when narrowing a region, the last visual selected region wasn't correctly
restored (reported by ping, thanks!)
- some code cleanup
- recursive narrowing was broken, fix it (reported by ping, thanks!)
0.29: Aug 20, 2012 {{{1
- Use ! to have the narrowed buffer not opened in a new window (suggested by
Greg Sexton thanks!, issue #8
https://github.com/chrisbra/NrrwRgn/issues/8)
- Fix mappings for visual mode (https://github.com/chrisbra/NrrwRgn/issues/9,
reported by Sung Pae, thanks!)
- Fix problem with setting the filetype
(https://github.com/chrisbra/NrrwRgn/issues/10, reported by Hong Xu,
thanks!)
- Fix some minor problems, when using ! mode
0.28: Jun 03, 2012 {{{1
- Plugin did not store last narrowed region when narrowed window was moved to
another tabpage (reported by Ben Fritz, thanks!)
0.27: May 17, 2012 {{{1
- When using |:NR| on a line that is folded, include the whole folded region
in the Narrowed window.
- Better filetype detection for comments
- Error handling, when doing |:NRM| without doing |:NRP| first
- Use |:NRP!| to clear the old selection
- Don't load the autoload script when sourcing the plugin script
(reported by Sergey Khorev, thanks!)
- Vim 7.3.449 introduced E855, prevent this error.
- |:NRL|
- |NRM| did not correctly parse the list of lines provided by |:NRP|
- highlighted pattern for blockwise visual narrowed regions was wrong
- Saving blockwise visual selected regions back, could corrupt the contents
0.26: Jan 02, 2012 {{{1
- Fix issue https://github.com/chrisbra/NrrwRgn/issues/7
(reported by Alessio B., thanks!)
0.25: Nov 08, 2011 {{{1
- updated documentation (patch by Jean, thanks!)
- make it possible, to not sync the narrowed buffer back by disabling
it using |:NRSyncOnWrite| |:NRNoSyncOnWrite|
0.24: Oct 24, 2011 {{{1
- error on vim.org page, reuploaded version 0.22 as 0.24
0.23: Oct 24, 2011 {{{1
- (wrongly uploaded to vim.org)
0.22: Oct 24, 2011 {{{1
- Allow customization via the use of hooks (|NR-hooks|)
0.21: July 26, 2011 {{{1
- Fix undefined variable adjust_line_numbers
https://github.com/chrisbra/NrrwRgn/issues/5 (reported by jmcantrell,
thanks!)
0.20: July 25, 2011 {{{1
- allow customization via the g:nrrw_topbot_leftright variable (Thanks Herbert
Sitz!)
- allow what options will be applied using the g:nrrw_custom_options dict
(suggested by Herbert Sitz. Thanks!)
- NRV didn't hightlight the region that was selected (reported by Herbert
Sitz, thanks!)
- use the g:nrrw_rgn_protect variable, to prevent that the original buffer
will be protected. This is useful, if you narrow several regions of the same
buffer and want to write those changes indepentently (reported by kolyuchiy
in https://github.com/chrisbra/NrrwRgn/issues/3, Thanks!)
- fix an error with not correctly deleting the highlighted region, that was
discovered when reporting issue 3 (see above). (Reported by kolyuchiy,
thanks!)
- Catch errors, when setting window local options. (Patch by Sung Pae,
Thanks!)
0.19: May 22, 2011 {{{1
- fix issue 2 from github https://github.com/chrisbra/NrrwRgn/issues/2
(Widening does not work, if the narrowed windows have been moved to a new
tabspace). Reported by vanschelven, thanks!
0.18: December 10, 2010 {{{1
- experimental feature: Allow to Narrow several different regions at once
using :g/pattern/NRP and afterwards calling :NRM
(This only works linewise. Should that be made possible for any reagion?)
- disable folds, before writing changes back, otherwise chances are, you'll
lose more data then wanted
- code cleanup
0.17: November 23, 2010 {{{1
- cache the options, that will be set (instead of parsing
$VIMRUNTIME/doc/options.txt every time) in the Narrowed Window
- getting the options didn't work, when using an autocommand like this:
autocmd BufEnter * cd %:p:h
(reported by Xu Hong, Thanks!)
- :q didn't clean up the Narrowed Buffer correctly. Fix this
- some code cleanup
0.16: November 16, 2010 {{{1
- Bugfix: copy all local options to the narrowed window (reported by Xu Hong,
Thanks!)
0.15: August 26, 2010 {{{1
- Bugfix: minor documentation update (reported by Hong Xu, Thanks!)
0.14: August 26, 2010 {{{1
- Bugfix: :only in the original buffer resulted in errors (reported by Adam
Monsen, Thanks!)
0.13: August 22, 2010 {{{1
- Unified Diff Handling (experimental feature)
0.12: July 29, 2010 {{{1
- Version 0.11, wasn't packaged correctly and the vimball file
contained some garbage. (Thanks Dennis Hostetler!)
0.11: July 28, 2010 {{{1
- Don't set 'winfixwidth' and 'winfixheight' (suggested by Charles Campbell)
0.10: May 20, 2010 {{{1
- Restore cursor position using winrestview() and winsaveview()
- fix a bug, that prevented the use of visual narrowing
- Make sure when closing the narrowed buffer, the content will be written to
the right original region
- use topleft for opening the Narrowed window
- check, that the original buffer is still available
- If you Narrow the complete buffer using :NRV and write the changes back, an
additional trailing line is inserted. Remove that line.
- When writing the changes back, update the highlighting.
0.9: May 20, 2010 {{{1
- It is now possible to Narrow a window recursively. This allows to have
several narrowed windows, and allows for example to only diff certain
regions (as was suggested in a recent thread at the vim_use mailinglist:
http://groups.google.com/group/vim_use/msg/05d7fd9bd1556f0e) therefore, the
use for the g:nrrw_rgn_sepwin variable isn't necessary anymore.
- Small documentation updates
0.8: May 18, 2010 {{{1
- the g:nrrw_rgn_sepwin variable can be used to force separate Narrowed
Windows, so you could easily diff those windows.
- make the separating of several windows a little bit safer (look at the
bufnr(), so it should work without problems for several buffers)
- switch from script local variables to buffer local variables, so narrowing
for several buffers should work.
- set 'winfixheight' for narrowed window
- Added command :NRV (suggested by Charles Campbell, thanks!)
- added error handling, in case :NRV is called, without a selected region
- take care of beeps, when calling :NRV
- output WarningMsg
0.7: May 17, 2010 {{{1
- really use the black hole register for deleting the old buffer contents in
the narrowed buffer (suggestion by esquifit in
http://groups.google.com/group/comp.editors/msg/3eb3e3a7c68597db)
- make autocommand nesting, so the highlighting will be removed when writing
the buffer contents.
- Use g:nrrw_rgn_nohl variable to disable highlighting (as this can be
disturbing).
0.6: May 04, 2010 {{{1
- the previous version had problems restoring the orig buffer, this version
fixes it (highlighting and setl ma did not work correctly)
0.5: May 04, 2010 {{{1
- The mapping that allows for narrowing a visually selected range, did not
work. (Fixed!)
- Make :WidenRegion work as expected (close the widened window) (unreleased)
0.4: Apr 28, 2010 {{{1
- Highlight narrowed region in the original buffer
- Save and Restore search-register
- Provide shortcut commands |:NR|
- Provide command |:NW| and |:NarrowWindow|
- Make plugin autoloadable
- Enable GLVS (see |:GLVS|)
- Provide Documenation (:h NarrowRegion)
- Distribute Plugin as vimball |pi_vimball.txt|
0.3: Apr 28, 2010 {{{1
- Initial upload
- development versions are available at the github repository
- put plugin on a public repository (http://github.com/chrisbra/NrrwRgn)
}}}
==============================================================================
Modeline:
vim:tw=78:ts=8:ft=help:et:fdm=marker:fdl=0:norl