Cegah penyegaran layar sampai fungsi selesai

10

Saya memiliki fungsi yang banyak bergerak dan mengeluarkan teks ke buffer vim saat ini, dan ketika saya menjalankannya, melihat semua yang terjadi pada kecepatan yang menyilaukan agak membingungkan.

Bagaimana saya bisa membekukan layar sampai fungsi selesai?

Inilah fungsi yang dimaksud:

function! MakeChoices()
    :let save_view = winsaveview()
    let start = line('.')

    "Locate previous *choice. (b=backwards, W=nowrap, n=doNot move cursor)
    let choiceStartLine = search('^*choice', 'bW')

    if !choiceStartLine
        echo "No *choice found. (*choice must not be indented. This is to avoid finding *choice blocks nested in another *choice block.)"
        return -1
    endif
    "return getline(target_line_num, target_line_num+4)
    "Locate end of *choice block
    "echo getline(choiceStartLine, choiceStartLine+2)
    let choiceEndLine = search('^\S.*', 'W') "End is first line that starts with non-whitespace

    "If above search fails, might be at bottom of buffer
    if choiceEndLine == 0
        let choiceEndLine = search('^$', 'W') "End is first empty line
    endif

    "Now go back up to the last *goto
    let choiceEndLine = search('*goto', 'bW')

    "Get the entire *choice block and put it in gotoBlock
    let gotoBlock = getline(choiceStartLine, choiceEndLine)

    "Make labelArray (contains all labels to goto)
    let labelArray = []

    for cur in gotoBlock
        if match(cur, '*goto') != -1
            "echo 'cur: '.cur
            let curParsed = matchlist(cur, '*goto \(\S\+\)')
            "echo curParsed
            if len(curParsed) > 1
                let curLabel = curParsed[1]
            else
                echo 'ERROR: Bad *goto ('.cur.')'
                return -1
            endif
            call add(labelArray, curLabel)  
        endif
    endfor

    "Restore window to what it looked like (in case the searches scrolled
    "it)
    call winrestview(save_view)

    "Make newline after choice block if needed
    if strlen(getline(choiceEndLine+1)) > 0
        echo 'big line: '.getline(choiceEndLine+1)
        call cursor(choiceEndLine, 1)
        put=''
    endif

    call cursor(choiceEndLine+1, 1)

    "Put the new label blocks
    let skippedLabels = ''
    let numNewLabels = 0
    for cur in labelArray
        if !search('*label '.cur, 'wn')
            let numNewLabels += 1
            put='*label '.cur
            put='[This option is yet to be written.]'
            put=''
        else
            let skippedLabels .= cur.' '
        endif
    endfor

    "Remove trailing blank lines (Up to a point)
    let nextlines = getline(line('.')+1, line('.')+3)
    if len(nextlines) == 3
        if nextlines[0] == '' && nextlines[1] == '' && nextlines[2] == ''
            normal "_3dd
        elseif nextlines[0] == '' && nextlines[1] == ''
            normal "_2dd
        elseif nextlines[0] == ''
            normal "_dd
        endif
    endif

    "Move to first label's text (use ctrl-v ctrl-m to input the <CR> at
    "end)
    if numNewLabels != 0
        call cursor(choiceEndLine, 1)
        normal /\[This option is yet to be written.\]
        let @/='\[This option is yet to be written\.\]'
    endif

    "Print status message
    if len(skippedLabels) > 0
        echo 'Skipped: '.skippedLabels
    else
        echo 'New labels created: '.numNewLabels
    endif
endfunction
Flurrywinde
sumber
2
Apakah :set lazyredrawmembantu?
VanLaser
Maaf tidak. Itu hanya membantu makro. Saya baru saja mencobanya, dan itu tidak berfungsi untuk fungsi saya.
Flurrywinde
2
Saya tidak tahu cara untuk melakukan ini, selain mungkin membekukan jendela terminal (yang tidak akan bekerja untuk gVim). Tapi mungkin ada cara lain untuk membuat fungsi Anda berjalan dengan lebih sedikit pembaruan layar? Akan sangat membantu jika Anda memposting fungsi Anda ;-)
Martin Tournoij
Anda memintanya, @Carpetsmoker. ;-) Fungsi ditambahkan. (Agak panjang.)
Flurrywinde

Jawaban:

5

Saya pikir masalahnya bukan :lazyredrawyang, seperti yang saya mengerti dari dokumen, harus berfungsi untuk fungsi (lihat :help :redraw, katanya "Berguna untuk memperbarui layar setengah jalan menjalankan skrip atau fungsi").

Masalahnya adalah Anda menggunakannya normaluntuk memperbarui buffer dan berfungsi seperti jika Anda benar-benar mengetik sesuatu dan di sini :lazyredrawtidak berpengaruh.

Alih-alih normalAnda perlu menggunakan fungsi manipulasi teks (seperti setline()) dan perintah ex (seperti :delete).

Bandingkan dua fungsi ini, yang pertama, MakeChangesNorm()akan melakukan beberapa pembaruan layar gila, sementara yang kedua, MakeChangesFunctions()akan melakukan pembaruan secara instan:

function! MakeChangesNorm()
    let lastline = line('$')
    norm gg
    let linenum = line('.')
    let lastline = line('$')
    while linenum < lastline
        norm ^
        norm s/choice/test/
        norm j
        normal "_3dd
        let linenum = line('.')
        let lastline = line('$')
    endwhile
endfunction


function! MakeChangesFunctions()
    norm gg
    let linenum = line('.')
    let lastline = line('$')
    while linenum < lastline
        let line = getline(linenum)
        " Substitute using substitute() and setline()
        let line = substitute(line, 'choice', 'test', '')
        call setline(linenum, line)
        " Delete lines using :delete
        execute '.,.+2delete _'
        let linenum = line('.')
        let lastline = line('$')
    endwhile
endfunction

File yang saya uji terlihat seperti ini:

*choice test2 test3 super
*choice test2 test3 super
*choice test2 test3 super
*choice test2 test3 super
*choice test2 test3 super
*choice test2 test3 super
*choice test2 test3 super
*choice test2 test3 super
*choice test2 test3 super
*choice test2 test3 super
... 60 lines like this ...
Boris Serebrov
sumber
Untuk lebih jelas; Apakah tidak ada cara untuk mengeluarkan beberapa perintah normal dan sepenuhnya menunda pembaruan layar sampai perintah "mengembalikan layar" berikutnya? Pemahaman saya adalah winsaveviewdan winrestviewhanya menyimpan lokasi kursor dan posisi relatif dari garis di jendela.
Luke Davis
Saya akan menanyakan ini dalam pertanyaan lain.
Luke Davis