Ngăn chặn làm mới màn hình cho đến khi chức năng hoàn thành


10

Tôi có một chức năng thực hiện nhiều thao tác di chuyển và xuất văn bản vào bộ đệm vim hiện tại, và khi tôi chạy nó, thấy tất cả những gì xảy ra ở tốc độ chói mắt là một chút bối rối.

Làm thế nào tôi có thể đóng băng màn hình cho đến khi chức năng được thực hiện?

Đây là chức năng trong câu hỏi:

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
:set lazyredrawgiúp được không?
VanLaser

Xin lỗi, không. Điều đó chỉ giúp cho các macro. Tôi vừa thử nó, và nó không hoạt động cho chức năng của tôi.
Flurrywinde 7/07/2015

2
Tôi không biết cách nào để làm điều này, ngoài việc đóng băng cửa sổ đầu cuối (không hoạt động cho gVim). Nhưng có lẽ có một cách khác để làm cho chức năng của bạn chạy với ít cập nhật màn hình hơn? Sẽ rất hữu ích nếu bạn đăng chức năng của mình ;-)
Martin Tournoij 7/07/2015

Bạn đã yêu cầu nó, @Carpetsmoker. ;-) Chức năng được thêm vào. (Nó khá dài.)
Flurrywinde

Câu trả lời:


5

Tôi nghĩ rằng vấn đề không phải là :lazyredraw, như tôi hiểu từ các tài liệu, nên hoạt động cho các chức năng (xem :help :redraw, nó nói "Hữu ích để cập nhật màn hình giữa chừng khi thực thi một tập lệnh hoặc chức năng").

Vấn đề là bạn sử dụng normalđể cập nhật bộ đệm và nó hoạt động như thế nào nếu bạn thực sự gõ một cái gì đó và ở đây :lazyredrawkhông có hiệu lực.

Thay vì normalbạn cần sử dụng các hàm thao tác văn bản (như setline()) và các lệnh ex (như :delete).

So sánh hai chức năng này, chức năng thứ nhất, MakeChangesNorm()sẽ thực hiện một số cập nhật màn hình điên rồ, trong khi chức năng thứ hai MakeChangesFunctions()sẽ thực hiện cập nhật ngay lập tức:

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

Các tập tin tôi đã kiểm tra nó trông như thế này:

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

Để rõ ràng; Có cách nào để ban hành một số lệnh thông thường và hoàn toàn hoãn cập nhật màn hình cho đến khi lệnh "khôi phục màn hình" tiếp theo không? Sự hiểu biết của tôi là winsaveviewwinrestviewchỉ đơn giản là lưu trữ vị trí con trỏ và vị trí tương đối của dòng trong cửa sổ.
Luke Davis

Tôi sẽ hỏi điều này trong một câu hỏi khác.
Luke Davis
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.