wovenhead
wovenhead

Reputation: 144

Vim Error events

I am working on a project to make vim compatible with screenreaders. As part of this project, I want to capture error messages and send them to the screen-reading process (via netbeans protocol). i.e. when a user attempts to edit a file that has read-only permissions, I want to capture the message: "E21: Cannot make changes, 'modifiable' is off" which gets sent to the command-line window, and fire off a bit of vim script. (I also want to capture the output of ex commands, which is related). For example, I would like something like:

:au OnError * : sendMessage()

However, no such "OnError" autocommand event exists. How can I simulate such an event?

The :redir command could allow me to redirect output to a buffer which is being monitored by netbeans (which would then allow me to capture the message). However, the changes are only written when :redir END is called. And because there are no events for errors, I would never know when to call :redir END.

None of the netbeans events (listed here ) offer any obvious help.

I know I can send the history via :messages, but this doesn't help a user who needs to immediately know about errors they've caused. And there are problems with trying to hack an event-loop into vim.

I have considered neovim but we want something that is totally cross-platform (gvim for windows). I am also concerned about their compatibility with other scripts and neovim's continued support.

Upvotes: 0

Views: 806

Answers (1)

romainl
romainl

Reputation: 196751

No Error event means no generic way to listen/capture generic errors. To capture an error within a user-defined vim function, do the following:

The safest solution would be — just like in any other programming language — to wrap your commands in a try|catch|endtry construction:

function! InsertFoo()
    try
        norm Ifoo
    catch /^Vim\%((\a\+)\)\=:E21/
        call SendMessage(v:exception, v:errmsg)
    endtry
endfunction

The function above will insert foo at the beginning of the current line in a writable buffer but throw an E21 exception when called in a read-only buffer (:help for example) and allow you to call your hypothetical SendMessage() (here with the error message and the full exception as arguments, use the one you prefer) that would presumably be in charge of displaying that information to your user.

Reference:

:help exception-handling
:help :try
:help :catch
:help v:errmsg
:help v:exception
:help errors
:help <errornumber>

Upvotes: 1

Related Questions