วิธีการคืนค่าตำแหน่งของเคอร์เซอร์หลังจากรันคำสั่งปกติ?


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|สตริงจะขยายตัว ดำเนินการจะพยายามดำเนินการคำสั่งนี้ แต่จะไม่ทำงานเพราะ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
ยินดีต้อนรับสู่เว็บไซต์ของเรา! เมื่อตอบพยายามให้คำอธิบายในคำตอบและไม่เพียง แต่เชื่อมโยงไปยังหน้าอื่น ๆ ลิงก์อาจตายและอาจมีข้อมูลที่ไม่เกี่ยวข้องจำนวนมากในการจัดเรียง
Tumbler41

1
ดังที่ฉันได้กล่าวไว้ในเอกสารที่ซ้ำกันดังนั้นการฟื้นฟูควรจะเกิดขึ้นในfinallyบล็อก มิฉะนั้นหากa:commandล้มเหลวจะไม่มีการคืนค่าใด ๆ
Luc Hermitte

ฉันเพิ่งแก้ไขฟังก์ชั่นของฉันตามที่คุณพูดถึง@Luc Hermitte
SergioAraujo

ตัวอย่างที่ดี - มีประโยชน์มาก
Charlie Dalsass
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.