4

I would like to create two functions, one for sending a message string to Vim's own messaging system and one to dump the message string to a file.

Now, I have already progressed in figuring this out with different approaches however, my solution is not elegant enough and sometimes the messages sent to :messages are getting lost on the status line at the moment of printing them out. However once I run :messages I can see those skipped messages in there. So this must be related to the way I deal with new lines etc. Here are bits of my script that should illustrate what approaches I have tried so far:

" Lets assume this is a part of the SendToStatus() function
" and it is a bit like a pseudo-code.
execute 'echohl' error
for l:line in split('My message.', '\\n')
  echomsg l:line
endfor
echohl NONE

The traditional way of sending the messages to :messages works fine on it's own. The problems start when I use the following to write the same message to a file:

" Lets assume this is a part of the SendToFile() function
" and this is also a bit like a pseudo-code.
try
    echon "\r"
    execute 'redir >> ' . l:file
    silent echomsg l:msgString
    silent echo "\n"
    silent! redir END
catch /E190:/
    throw s:myException('Cannot write to file: %s', l:file)
end-try

So when I execute these commands one after another like this:

function! SomeMoreComplexWrapper() abort
    ...
    SendToStatus('some message')
    SendToFile('some message')
    ....
    SendToStatus('some more messages')
    ....
    SendToStatus('some more messages')
    SendToFile('even more messages')
    ...
endfunction

The strings are written to the file with no issues what so ever, however, the status messages are getting lost on some occasions. It must be the way the echoing order is managed.

I have also tried the readfile() and writefile() approaches, which worked just fine. This helped me to take the process of echoing to a file out of the equation, thus removed the need of dealing with echo and echomsg on both sides and only keep echomsg to send the strings to the :message facility. However I need to store the contents of my log file into a list and append the new string to that every time I need to send something to the file, which I find a bit scary.

Could you please help me with this issue?

  • I am working on a fully functional example that will reproduce the issue. I will share that as soon as it works. However, I now know that in cases where SendToFile() is used consecutive, the following SendToStatus() will be dropped and will be only visible in the :message stream. – mbilyanov Nov 29 '15 at 19:59
1

The problem was related to that bit:

echon "\r"

... in the file dumper function, used to reset the cursor position. Stack multiple SendToFile() and you get the cursor aligned too many time causing the next echom commands to be not visible in the status line.

The solution (for now) is to use a variable s:isFileStreamActive that is set to 1 inside SendToFile() and to 0 inside SendToStatus(). In that way, consecutive echon "\r" commands can be skipped with an if statement:

if !s:isFileStreamActive
    echon "\r"
endif

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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