2

I have the following script to log various events:

augroup EventLogger
    autocmd!
    autocmd! BufWrite,BufEnter,User * call LogOutput(" getEventType() ")
augroup END

How would I getEventType() from within an autocmd, or any function for that matter. Here is what I've tried so far:

function PrintContext()
    echom v:event
endfunction
augroup EventLogger
    autocmd!
    autocmd! BufWrite,BufEnter,User * call PrintContext()
augroup END

But this just prints {}, so I'm not sure how to collect the 'eventtype'.

1 Answer 1

3

You can't.

But there is an open issue which asks for this feature, as well as an item in the todo list which suggests that such a feature would be merged if someone was willing to work on it:

Add <aevent>, which expands to the currently triggered autocommand event name. (Daniel Hahler, #4232) Or add it to v:event (easier to use but slightly more expensive).


In the meantime, you need one autocmd per event:

augroup EventLogger
    autocmd!
    autocmd BufWrite * call LogOutput('BufWrite')
    autocmd BufEnter * call LogOutput('BufEnter')
    autocmd User * call LogOutput('User')
augroup END

For all events, try something like this:

augroup EventLogger
    autocmd!
    let events = getcompletion('', 'event')
    for event in events
        exe printf('au %s * call LogOutput("%s")', event, event)
    endfor
augroup END

I get the following when trying to do some things: Error detected while processing FuncUndefined Autocommands for "*": E218: autocommand nesting too deep

Don't install autocmds for events which cause such issues, such as FuncUndefined:

augroup EventLogger
    autocmd!
    let s:EVENTS = getcompletion('', 'event')
    const s:DANGEROUS =<< trim END
        BufReadCmd
        BufWriteCmd
        FileAppendCmd
        FileReadCmd
        FileWriteCmd
        FuncUndefined
        SourceCmd
    END
    const s:SYNONYMS =<< trim END
        BufCreate
        BufRead
        BufWrite
    END
    const s:TOO_FREQUENT =<< trim END
        CmdlineChanged
        CmdlineEnter
        CmdlineLeave
        SafeState
        SafeStateAgain
    END
    call filter(s:EVENTS, {_,v -> index(s:DANGEROUS + s:SYNONYMS + s:TOO_FREQUENT, v, 0, 1) == -1})
    for s:event in s:EVENTS
        exe printf('au %s * call LogOutput("%s")', s:event, s:event)
    endfor
    unlet! s:event s:EVENTS s:DANGEROUS s:SYNONYMS s:TOO_FREQUENT
augroup END
3
  • awesome thanks for this, though even this is fraught with some issues, it seems you can only call them so many times! I get the following when trying to do some things: Error detected while processing FuncUndefined Autocommands for "*": E218: autocommand nesting too deep
    – David542
    Commented Jun 27, 2020 at 23:22
  • This may be a bit of an odd question, but would you say that there are a "top ten" or twenty events or so that do most of the work? Or are there tons of varied events that are called all the time, and it's needed to understand most of them?
    – David542
    Commented Jun 27, 2020 at 23:23
  • so cool, thanks for the updates and all this is so helpful for me, I've made a function to be able to toggle certain events to track (or allow all to show).
    – David542
    Commented Jun 28, 2020 at 2:21

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.