我有一些Vim功能可以更改文档格式。当我调用此函数时,我目前使用类似以下内容来保存和恢复我的光标位置:
func! Foo()
:norm mz
...
:norm `z
endf
这样可以正确保存光标位置,但有时会改变窗口位置,以便当前行从靠近屏幕顶部移动到靠近底部,反之亦然。有没有办法保留光标位置和线的屏幕位置?
答案 0 :(得分:26)
let l:winview = winsaveview()
" do stuff
call winrestview(l:winview)
这应该完全按照你想要它做的,可能除了光标上方的行数改变外(我怀疑光标上方的删除行会产生向下移动光标的效果)。
答案 1 :(得分:6)
您可以为窗口中显示的第一个屏幕行保存标记,并将其还原。在整个缓冲区上执行g?
命令并恢复两个位置的示例:
:noremap <F11> mkHmlggg?G`lzt`k
完成命令:
mk
:为当前位置设置标记k
H
:转到屏幕第一行ml
:为此位置设置标记l
ggg?G
:执行命令: jump to mark
l` zt
:将此行设置为第一个屏幕行: jump to mark
k` 答案 2 :(得分:6)
Just:h getpos()
let save_cursor = getpos(".")
" MoveTheCursorAround
call setpos('.', save_cursor)
答案 3 :(得分:3)
你可以使用getline()保存当前缓冲行,使用winline()来保存当前窗口行。
所以它会是这样的:
可能会有一些特殊情况需要处理,例如位置接近文件的结尾或开头,或者文件是否小于窗口大小。
答案 4 :(得分:0)
有一个plugin但是我使用了这样一个函数:
if !exists('*Preserve')
function! Preserve(command)
try
" Preparation: save last search, and cursor position.
let l:win_view = winsaveview()
let l:old_query = getreg('/')
silent! execute 'keepjumps ' . a:command
finally
" Clean up: restore previous search history, and cursor position
call winrestview(l:win_view)
call setreg('/', l:old_query)
endtry
endfunction
endif
然后我称之为清理尾随空格
fun! CleanExtraSpaces()
call Preserve(':%s/\s\+$//ge')
endfun
com! Cls :call CleanExtraSpaces()
au! BufwritePre * :call CleanExtraSpaces()
del blank lines
fun! DelBlankLines()
call Preserve(':%s/^\n\{2,}/\r/ge')
endfun
command! -nargs=0 DelBlank :call DelBlankLines()
并更改标题(上次修改)信息
fun! ChangeHeader()
call Preserve(':1,5s/Last Change: \zs.*/\=strftime("%c")/e')
endfun
command! -nargs=0 CH :call ChangeHeader()
au BufWritePost * :call ChangeHeader()