Impedire l'aggiornamento dello schermo fino al completamento della funzione


10

Ho una funzione che fa molto spostare e inviare il testo nel buffer vim corrente, e quando lo eseguo, vedere tutto ciò che accade ad una velocità accecante è un po 'sconcertante.

Come posso bloccare lo schermo fino al termine della funzione?

Ecco la funzione in questione:

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

2
Does :set lazyredrawaiuto?
VanLaser,

Scusa no. Questo aiuta solo per le macro. L'ho appena provato e non ha funzionato per la mia funzione.
Flurrywinde,

2
Non conosco alcun modo per farlo, tranne forse congelare la finestra del terminale (che non funzionerà per gVim). Ma forse c'è un altro modo per far funzionare la tua funzione con meno aggiornamenti dello schermo? Sarebbe utile se hai pubblicato la tua funzione ;-)
Martin Tournoij

L'hai chiesto, @Carpetsmoker. ;-) Funzione aggiunta. (È piuttosto lungo.)
Flurrywinde

Risposte:


5

Penso che il problema non sia :lazyredrawche, come ho capito dai documenti, dovrebbe funzionare per le funzioni (vedi :help :redraw, dice "Utile per aggiornare lo schermo a metà esecuzione di uno script o di una funzione").

Il problema è che usi normalper aggiornare il buffer e funziona come se effettivamente scrivessi qualcosa e qui :lazyredrawnon ha effetto.

Invece di normalusare le funzioni di manipolazione del testo (come setline()) ed ex comandi (come :delete).

Confronta queste due funzioni, la prima MakeChangesNorm()eseguirà alcuni aggiornamenti pazzi dello schermo, mentre la seconda MakeChangesFunctions()eseguirà l'aggiornamento all'istante:

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

Il file su cui l'ho provato è simile al seguente:

*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 ...

Per essere chiari; non c'è modo di emettere diversi comandi normali e rimandare completamente l'aggiornamento dello schermo fino a un successivo comando di "ripristino dello schermo"? La mia comprensione è winsaveviewe winrestviewsemplicemente memorizzare la posizione del cursore e la posizione relativa della linea nella finestra.
Luke Davis,

Lo farò in un'altra domanda.
Luke Davis,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.