Bagaimana cara mengembalikan posisi kursor setelah menjalankan perintah normal?

13

Saya mencoba kode fungsi yang menggantikan karakter di kolom keenam dari baris saya saat ini dengan simbol dolar ( $), tetapi saya ingin kursor saya tetap pada posisi itu sebelum memanggil fungsi.

Jadi saya mencoba menyimpan kolom saat ini, menjalankan perubahan saya, dan kemudian kembali dengan fungsi berikut:

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

Saya mungkin salah mengerti sesuatu tentang executeperintah ... Atau mungkin saya harus membuat string berisi perintah yang ingin saya jalankan?

Feffe
sumber

Jawaban:

19

Anda harus menggunakan getpos():

Untuk menghemat posisi Anda dalam suatu variabel:

let save_pos = getpos(".")

getpos()mengambil sebagai argumen sebagai tanda, di sini "."mewakili posisi kursor Anda saat ini.

Dan untuk mengembalikannya:

call setpos('.', save_pos)

Di sini argumen pertama menunjukkan bahwa Anda akan memindahkan tanda posisi saat ini dari kursor Anda (maka posisi Anda saat ini) dan yang kedua adalah tempat untuk meletakkan tanda (posisi yang Anda simpan sebelumnya).

Fungsi Anda akan terlihat seperti ini:

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

Untuk lebih jelasnya lihat: :h getpos()dan:h setpos()


Untuk detail lebih lanjut tentang penggunaan Anda execute: fungsi ini akan mengambil string dan menjalankannya. String Anda hanya dapat berupa karakter-karakter dengan kode sandi antara tanda kutip ganda atau konten variabel.

Ketika Anda menulis

execute col_number."|"

Jika Anda berada di kolom ke-12 string yang diperluas akan menjadi 12|. Jalankan akan mencoba untuk mengeksekusi perintah ini tetapi tidak akan berhasil karena 12|bukan fungsi vimscript tetapi perintah mode normal.

Untuk menjalankannya dari vimscript Anda harus mengatakan "jalankan itu seolah-olah saya telah mengetiknya dalam mode normal`, itulah yang digunakan untuk normal.

Jadi tanpa eksekusi Anda akan menulis:

normal 12|

Sekarang untuk membuat executepanggilan Anda berfungsi, Anda harus menambahkan normalkata kunci ke string Anda yang diperluas, seperti ini:

execute "normal " . col_number . "|"
statox
sumber
Terima kasih atas solusi ini (ini yang akan saya gunakan), tetapi apakah ada cara lain, menggunakan variabel "col_number" saya? Itu akan memungkinkan saya untuk lebih memahami bagaimana menjalankan / bekerja normal.
Feffe
1
@Feffe: Pembaruan saya harus menjelaskan ini :-)
statox
3

Fungsi ini juga menyimpan register pencarian Anda. Jadi Anda bisa memberikan perintah sebagai argumen di atasnya.

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

Beberapa penjelasan

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

Sebagai contoh:

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

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

SergioAraujo
sumber
1
Selamat datang di situs kami! Saat menjawab, coba berikan penjelasan di dalam jawaban dan jangan hanya tautan ke halaman lain. Tautan dapat mati, dan mungkin memiliki banyak informasi yang tidak relevan untuk dipilah.
Tumbler41
1
Seperti yang saya katakan dalam duplikat SO, pemulihan harus terjadi dalam satu finallyblok. Kalau tidak, jika a:commandgagal, tidak ada yang akan dipulihkan.
Luc Hermitte
Saya baru saja memperbaiki fungsi saya seperti yang Anda sebutkan @Luc Hermitte
SergioAraujo
Contoh yang bagus - sangat berguna.
Charlie Dalsass