0

How do I set up Vim to achieve the effect in the title?

1
  • 3
    I don't know about N minutes, but have a look at the readonly and modifiable options
    – D. Ben Knoble
    Commented Aug 20, 2021 at 19:57

1 Answer 1

0

Your question is pretty light on the details but I was in the mood for some vimscripting so this is my interpretation...

" How many minutes to unblock writes
let g:allowwritemins = 5

func! CheckWriteBlock(bufname)
    if !exists("b:blockwrite")
        let b:blockwrite = 1
    endif

    if !b:blockwrite
        " Not currently blocked. Write the file and unset modified flag
        w
        set nomodified
        return
    endif

    if input(printf("Warning: Writes are blocked. Enable writes for the next %d minutes? ", g:allowwritemins)) =~? "y"
        let b:blockwrite = 0
        " This will start a timer for configured number of minutes
        " after which blockwrite flag will be reset.
        call timer_start(g:allowwritemins * 60 * 1000, {-> setbufvar(a:bufname, "blockwrite", 1)})
        redraw
        echom "You may write the file now."
    endif
endfunc

augroup writeblock
  autocmd!
  " BufWriteCmd is called before the write and requires the coder to
  " do the write themselves if that's what they want.
  autocmd BufWriteCmd * call CheckWriteBlock(bufname())
augroup END

Put all of that in your vimrc and for each file that you try to write it will block and ask you if you want to unblock writes. If you enter Y (case insensitive; followed by Enter) then for the configured number of minutes you can then do :w.

Update: OP asked about using this only on designated buffers rather than any and all buffers. My suggestion was to repurpose b:blockwrite as a user-controlled flag. It is not defined by default and manually set to 1 for buffers to be protected. That would require just a few changes to the function. The first conditional block is removed and the second conditional is modified. That gives us...

func! CheckWriteBlock(bufname)
    " Flag not defined or it's disabled (equal to 0)
    if !exists("b:blockwrite") || !b:blockwrite
        " Write the file and unset modified flag
        w
        set nomodified
        return
    endif

    " Last block remains the same so
    ...snip...
endfunc

I'd also create a convenience mapping for toggling the flag, e.g. ...

nnoremap <leader>b :let b:blockwrite = exists("b:blockwrite") ? !b:blockwrite : 1<cr>
6
  • Hm, is the timer callback guaranteed to execute in the buffer from which it was created? If I switch buffers before it runs, I have a feeling it will set the wrong buffer’s variable. I wonder if it would be simpler too just to toggle the readonly or modifiable flags (editable vs writable)?
    – D. Ben Knoble
    Commented Aug 21, 2021 at 2:03
  • I was aware of that already and knew what to do but wanted to hear if this was even on the right track as far as what OP wants. But since you made it public I fixed it.
    – B Layer
    Commented Aug 21, 2021 at 3:33
  • @B Layer, this is exactly the functionality I was looking for. Ty. Only tweaked one thing, bufname() requires an empty string to reference the current buffer, i.e. bufname(''). stackoverflow.com/a/13706784/7503825. Commented Aug 21, 2021 at 6:59
  • @CharlesKong Glad I guessed right. :) FYI, :h bufname() says "if {buf} is omitted the current buffer is used" and I verified that bufname() does indeed work. If that doesn't work for you maybe you're using an older version of Vim...?
    – B Layer
    Commented Aug 21, 2021 at 8:23
  • I see. Strange to see the docs and user experience contradicting. I've got Vim 8.1. BTW if I wanted to apply your func on manually selected files and not all files (still using the event hook), what should I look into in the docs? I'm not looking to persist this list between Vim instances (i.e. neither concurrently running processes nor over time via :mksession). Commented Aug 21, 2021 at 8:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.