일반 명령을 실행 한 후 커서 위치를 복원하는 방법은 무엇입니까?


13

현재 줄의 여섯 번째 열에있는 문자를 달러 기호 ( $)로 바꾸는 함수를 코딩하려고 하지만 커서를 함수를 호출하기 전의 위치에 유지하고 싶습니다.

그래서 현재 열을 저장하고 변경 사항을 실행 한 다음 다음 기능을 다시 시도했습니다.

function! DollarSplit()
   let col_number=col(".")     "stores the current column number of the cursor
   normal! 6|r$                " replaces the 6th caracter in line with a $
   execute col_number."|" 
endfunction

execute명령 에 대해 잘못 이해 했을 수도 있습니다 ... 아니면 실행하려는 명령이 포함 된 문자열을 만들어야합니까?

답변:


19

사용해야합니다 getpos():

변수에 위치를 저장하려면 다음을 수행하십시오.

let save_pos = getpos(".")

getpos()인수로 표시, 여기 "."커서의 현재 위치를 나타냅니다.

그리고 그것을 복원하려면 :

call setpos('.', save_pos)

여기에서 첫 번째 인수는 커서의 현재 위치 표시를 이동하므로 (현재 위치) 두 번째 인수는 표시를 넣을 위치 (이전에 저장 한 위치)입니다.

함수는 다음과 같습니다.

function! DollarSplit()
   let save_pos = getpos(".")
   normal! 6|r$                " replaces the 6th caracter in line with a $
   call setpos(".", save_pos)
endfunction

자세한 내용은 다음을 참조하십시오 :h getpos():h setpos()


사용법에 대한 자세한 내용은 execute이 함수는 문자열을 가져 와서 실행합니다. 문자열은 큰 따옴표 또는 변수 내용 사이의 하드 코딩 된 문자 만 될 수 있습니다.

당신이 쓸 때

execute col_number."|"

12 번째 열에있는 경우 확장 문자열은입니다 12|. Execute는이 명령을 실행하려고 시도하지만 12|vimscript 기능이 아니라 일반 모드 명령이므로 작동하지 않습니다.

vimscript에서 실행하려면 "정상 모드에서 입력 한 것처럼 실행"이라고 말해야합니다.

따라서 실행하지 않으면 다음과 같이 작성했을 것입니다.

normal 12|

이제 execute전화를 걸 려면 다음 normal과 같이 확장 된 문자열에 키워드를 추가해야 합니다.

execute "normal " . col_number . "|"

이 솔루션에 감사드립니다 (사용할 솔루션입니다). "col_number"변수를 사용하여 다른 방법이 있습니까? 그것은 내가 어떻게 실행 / 정상 작업을 더 잘 이해할 수있게 해줄 것입니다.
Feffe

1
@Feffe : 내 업데이트는 이것을 명확히해야합니다 :-)
statox

3

이 기능은 검색 레지스터도 유지합니다. 따라서 명령을 인수로 전달할 수 있습니다.

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
            " try restore / reg and cursor position
            call winrestview(l:win_view)
            call setreg('/', l:old_query)
        endtry
    endfunction
endif

일부 설명

let .......... used to set a variable
l:somevar .... local variable
winsaveview()  get information about window view
winrestview(lwinview) restores window view to its last status
getreg('/')    used to store the last search in a variable
keepjumps      used to performe any change without change jumplis
. a:command    concatenates any given command with keepjumps

예를 들면 다음과 같습니다.

"Reident file without moving cursor position
:call Preserve('normal! gg=G')

"Reindent command using 'Preserve()'
command! -nargs=0 Reindent :call Preserve('exec "normal! gg=G"')

"If you have any change log at your file header
:call Preserve('1,5s/Last Change: \zs.*/\=strftime("%c")/e')

"Close all buffers but current one
" https://bitbucket.org/snippets/sergio/9nbyGy
command! BufOnly silent! call Preserve("exec '%bd|e#|bd#'")

출처 : https://technotales.wordpress.com/2010/03/31/preserve-a-vim-function-that-keeps-your-state/


1
우리 사이트에 오신 것을 환영합니다! 답변 할 때 다른 페이지에 대한 링크가 아니라 답변 내에 설명을 해보십시오. 링크는 죽을 수 있으며 정렬 할 관련없는 정보가 많이있을 수 있습니다.
텀블러 41

1
SO 중복에서 말했듯이 복원은 한 finally블록으로 이루어져야합니다 . 그렇지 않으면 a:command실패하면 아무 것도 복원되지 않습니다.
Luc Hermitte


좋은 예-매우 유용합니다.
Charlie Dalsass
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.