Normal bir komut yürüdükten sonra imlecin konumu nasıl geri yüklenir?


13

Geçerli satırım altıncı sütunda karakteri bir dolar simgesi ( $) ile değiştiren bir işlevi kodlamaya çalışıyorum , ancak imlecim işlevi çağırmadan önce olduğu konumda kalmak istiyorum.

Bu yüzden geçerli sütunu depolamaya, değişikliklerimi yürütmeye ve sonra aşağıdaki işlevle geri gelmeye çalıştım:

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

Muhtemelen executekomutla ilgili bir şeyi yanlış anlıyorum ... Ya da yürütmek istediğim komutu içeren bir dize oluşturmalıyım?

Yanıtlar:


20

Kullanmalısınız getpos():

Bir değişken içindeki konumunuzu kaydetmek için:

let save_pos = getpos(".")

getpos()argüman olarak bir işaret alır, burada "."imlecinizin geçerli konumunu temsil eder.

Ve geri yüklemek için:

call setpos('.', save_pos)

Burada ilk argüman imlecinizin mevcut pozisyonunun işaretini hareket ettireceğinizi (dolayısıyla mevcut pozisyonunuz) ve ikincisi işareti nereye koyacağınızı (daha önce kaydettiğiniz pozisyon) göstermektedir.

İşleviniz şöyle görünecektir:

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

Daha fazla ayrıntı için bakınız: :h getpos()ve:h setpos()


Kullanımınız hakkında daha fazla bilgi için execute: bu işlev bir dize alır ve yürütür. Dizeniz yalnızca çift tırnak işaretleri veya değişkenlerin içerikleri arasında sabit kodlanmış karakterler olabilir.

Yazdığın zaman

execute col_number."|"

12. sütundaysanız, genişletilmiş dize olacaktır 12|. Execute bu komutu yürütmeye çalışacaktır 12|, ancak bir vimscript işlevi değil, normal mod komutu olduğu için çalışmaz.

Bir vimscript'den yürütmek için "normal modda yazmışım gibi çalıştır" demelisiniz, bunun için normal kullanılır.

Yani infaz olmadan şunu yazmış olursunuz:

normal 12|

Şimdi executeçağrınızın çalışması için normalanahtar kelimeyi genişletilmiş dizenize aşağıdaki gibi eklemeniz gerekir:

execute "normal " . col_number . "|"

Bu çözüm için teşekkürler (kullanacağım), ancak "col_number" değişkenimi kullanarak başka bir yol var mı? Bu, nasıl çalıştığını / normal çalışmayı daha iyi anlamama izin verir.
Feffe

1
@Feffe: Güncellemem bunu netleştirmeli :-)
statox

3

Bu işlev arama kaydınızı da tutar. Böylece komutunuzu argüman olarak iletebilirsiniz.

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

Bazı açıklamalar

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

Örneğin:

"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#'")

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


1
Sitemize hoşgeldiniz! Yanıtlarken, yalnızca diğer sayfalara olan bağlantıları değil, cevap içinde bazı açıklamalar yapmaya çalışın. Bağlantılar ölebilir ve sıralanacak çok alakasız bilgiye sahip olabilir.
Tumbler41

1
SO kopyasında söylediğim gibi, restorasyon bir finallyblokta gerçekleşmelidir. Aksi takdirde, a:commandbaşarısız olursa hiçbir şey geri yüklenmez.
Luc Hermitte


Harika örnekler - çok faydalı.
Charlie Dalsass
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.