Vim脚本:在函数调用中保留光标位置和屏幕视图

时间:2009-06-05 04:31:17

标签: vim

我有一些Vim功能可以更改文档格式。当我调用此函数时,我目前使用类似以下内容来保存和恢复我的光标位置:

func! Foo()
  :norm mz
  ...
  :norm `z
endf

这样可以正确保存光标位置,但有时会改变窗口位置,以便当前行从靠近屏幕顶部移动到靠近底部,反之亦然。有没有办法保留光标位置和线的屏幕位置?

5 个答案:

答案 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:将此行设置为第一个屏幕行
  • `'K : jump to mark k`

答案 2 :(得分:6)

Just:h getpos()

let save_cursor = getpos(".")
" MoveTheCursorAround
call setpos('.', save_cursor)

答案 3 :(得分:3)

你可以使用getline()保存当前缓冲行,使用winline()来保存当前窗口行。

所以它会是这样的:

  • 使用winline()保存窗口行
  • 将光标移动到窗口顶部:normal! H
  • 使用getline()保存缓冲行
  • ...
  • 恢复缓冲行:exec'正常! '.myline.'G'
  • 滚动到顶部:普通zt
  • 然后恢复原来的窗口行:exec'正常! '.mywinline.'H'

可能会有一些特殊情况需要处理,例如位置接近文件的结尾或开头,或者文件是否小于窗口大小。

答案 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()