Подтвердить что ты не робот

Вимм-скрипты: сохранение позиции курсора и экрана в вызове функции

У меня есть некоторые функции Vim, которые вносят изменения в формат документа. Когда я вызываю эту функцию, в настоящее время я использую что-то вроде следующего для сохранения и восстановления позиции курсора:

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

Это правильно сохраняет положение курсора, но иногда оно меняет положение окна, так что текущая строка перемещается от верхней части экрана к нижней или наоборот. Есть ли способ сохранить позицию курсора и положение на экране линии?

4b9b3361

Ответ 1

let l:winview = winsaveview()
" do stuff
call winrestview(l:winview)

Это в значительной степени сделает именно то, что вы хотите, возможно, за исключением того, что счетчик строк изменяется над курсором (я подозреваю, что удаленные строки над курсором будут иметь эффект перемещения курсора вниз).

Ответ 2

Вы можете сохранить отметку для первой экранной строки, которая отображается в окне, и восстановить ее. Пример, который выполняет команду g? для всего буфера и восстанавливает обе позиции:

:noremap <F11> mkHmlggg?G`lzt`k

Прогулка по команде:

  • mk: установить отметку k для текущей позиции
  • H: перейти к первой экранной строке
  • ml: установить отметку l для этой позиции
  • ggg?G: выполните команду
  • `` л : jump to mark L`
  • zt: установите для этой строки первую экранную строку
  • `` к : jump to mark k`

Ответ 3

Только: h getpos()

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

Ответ 4

вы можете использовать getline() для сохранения текущей строки буфера и winline() для сохранения текущей строки окна.

Итак, это будет выглядеть примерно так:

  • сохранить строку окна с winline()
  • переместите курсор в верхнюю часть окна: normal! ЧАС
  • сохранить строку буфера с помощью getline()
  • ...
  • восстановить строку буфера с помощью: exec 'normal! '.myline.'G'
  • прокрутите вверх, используя: normal zt
  • затем восстановить исходную строку окна: exec 'normal! '.mywinline.'H'

Может быть несколько особых случаев, о которых вам придется позаботиться, например, если позиция находится ближе к концу или началу файла или размер файла меньше размера окна.

Ответ 5

Существует плагин но я использую одну функцию следующим образом:

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