mirror of
https://github.com/inkarkat/vim-ingo-library.git
synced 2026-05-29 11:18:51 +02:00
76 lines
3.0 KiB
VimL
76 lines
3.0 KiB
VimL
" ingo/view.vim: Functions for saving and restoring the window's view.
|
|
"
|
|
" DEPENDENCIES:
|
|
"
|
|
" Copyright: (C) 2019 Ingo Karkat
|
|
" The VIM LICENSE applies to this script; see ':help copyright'.
|
|
"
|
|
" Maintainer: Ingo Karkat <ingo@karkat.de>
|
|
|
|
" The functions here allow you to define internal mappings that, when they
|
|
" surround the right-hand side of your actual mapping, restore the current view
|
|
" in the current window. Define the right variant(s) based on the mapping
|
|
" mode(s), and whether a simple winsaveview() will do, or whether you need
|
|
" "extra strength" to relocate the current position via a temporary mark (when
|
|
" there are insertions / deletions above the current position, the recorded
|
|
" cursor position may be off).
|
|
" noremap <expr> <silent> <SID>(WinSaveView) ingo#view#Save(0)
|
|
" inoremap <expr> <silent> <SID>(WinSaveView) ingo#view#Save(0)
|
|
" noremap <expr> <silent> <SID>(WinSaveViewWithMark) ingo#view#Save(1)
|
|
" inoremap <expr> <silent> <SID>(WinSaveViewWithMark) ingo#view#Save(1)
|
|
" Use <Plug>(WinSaveView) from any mode at the beginning of a mapping to save
|
|
" the current window's view. This is a |:map-expr| which does not interfere with
|
|
" any pending <count> or mode.
|
|
"
|
|
" At the end of the mapping, use <Plug>(WinRestView) from normal mode to restore
|
|
" the view and cursor position.
|
|
" nnoremap <expr> <silent> <SID>(WinRestView) ingo#view#Restore()
|
|
" Example: >
|
|
" nnoremap <script> <SID>(WinSaveView)<SID>MyMapping<SID>(WinRestView)
|
|
" or :execute the ingo#view#RestoreCommands() directly (e.g. if the mapping asks
|
|
" for input).
|
|
|
|
let s:save_count = 0
|
|
function! ingo#view#Save( isUseMark )
|
|
let s:save_count = v:count
|
|
let w:save_view = winsaveview()
|
|
if a:isUseMark
|
|
try
|
|
let w:save_mark = ingo#plugin#marks#FindUnused()
|
|
let l:markExpr = "'" . w:save_mark
|
|
call setpos(l:markExpr, getpos('.'))
|
|
catch /^ReserveMarks:/
|
|
" If no marks are available, just use the saved view. Grabbing a
|
|
" used mark and clobber its position could be worse than just be off
|
|
" with the restored view.
|
|
unlet! w:save_mark
|
|
endtry
|
|
else
|
|
unlet! w:save_mark
|
|
endif
|
|
return ''
|
|
endfunction
|
|
function! ingo#view#RestoreCommands()
|
|
let l:commands = []
|
|
if exists('w:save_view')
|
|
call add(l:commands, 'call winrestview(w:save_view)|unlet w:save_view')
|
|
endif
|
|
if exists('w:save_mark')
|
|
call add(l:commands, printf("execute 'silent! normal! g`%s'|call setpos(\"'%s\", [0, 0, 0, 0])|unlet! w:save_mark", w:save_mark, w:save_mark))
|
|
endif
|
|
return join(l:commands, '|')
|
|
endfunction
|
|
function! ingo#view#Restore()
|
|
let l:commands = ingo#view#RestoreCommands()
|
|
return (empty(l:commands) ? '' : "\<C-\>\<C-n>:" . ingo#view#RestoreCommands() . "\<CR>")
|
|
endfunction
|
|
|
|
" ingo#view#Restore[Commands]() clobber v:count, but you can for instance pass a
|
|
" Funcref to ingo#view#RestoredCount as the a:defaultCount optional argument to
|
|
" the repeatableMapping.vim functions to consider the saved value.
|
|
function! ingo#view#RestoredCount()
|
|
return s:save_count
|
|
endfunction
|
|
|
|
" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
|