0

I have a function that counts the number of matches in a file using the substitute Ex command with the /n flag and returns the value. However, I cannot echo the answer because the status line is getting overwritten by the file name. In other words, I will do this:

:echo Myfun("pattern")

and the result will be:

"scratch1" [Modified][New file] 3 lines --100%--   

If I use the message history (echom) it clearly shows that the correct result is being generated and returned, but the message is getting overwritten by the "modified" message. I don't understand this because the script does not modify anything. Why is the status line getting overwritten?

The effect seems to be caused by bufdo. A minimal example of Myfun is the following:

function! Myfun( pattern )
    let command = '%s/'.a:pattern.'//gen'
    let count_pattern = 0
    bufdo let count_pattern += str2nr( strpart( execute( command ), 1 ) )
    return count_pattern
endfunction

If the environment has only one open buffer then the echo command works correctly, but if there are more than one buffers open, then the status line is getting overwritten. In other words, what is happening is the following sequence of events:

  1. function runs (switching buffers in the process)
  2. function returns a number it calculated
  3. echo command prints that number to the status line
  4. Vim writes ""example" [New file] --No lines in buffer--" to status line

So, after the command is over Vim is updating the status line if the buffer was changed at any point when the command executed. I need to prevent this from happening to see the result.

  • The status line and the Ex command line (where messages are written) are two different things; however, im not sure why the substitute command is outputting this with the n flag. Can you try using silent[!] ? – D. Ben Knoble Feb 3 '18 at 10:24
  • @DavidBenKnoble I am using the "e" flag already. The substitute command is not outputting the "Modified" status line, or anything else because it is being executed by the execute() function, so its output is collected to a local variable in the script. The problem is that Vim is overwriting the output of the echo command with the Modified status. So what happens is that the result of the :echo command is printed, but then immediately overwritten with "scratch1... etc". – Tyler Durden Feb 3 '18 at 11:07
  • Odd... frankly not sure whats causing that. Could be useful if you show the function in the question – D. Ben Knoble Feb 3 '18 at 11:11
  • @DavidBenKnoble I updated the question with more details and minimal example. – Tyler Durden Feb 3 '18 at 11:30
  • Can we silence the bufdo ? – D. Ben Knoble Feb 3 '18 at 11:31
2

Your problem comes from the fact that bufdo loads each buffer in the current window and then Vim will output in the command line (note: Note the statusline, that is a different area!) that it is editing the buffer and it has been modified.

I suppose, you have 'hidden' set, otherwise, you wouldn't be able to switch buffers.

BTW: the result of your function is printed correctly, it is just that afterwards the message area will get overwritten by another message.

The simplest way would be to use :sil :bufdo to hide those messages or you can set the 'shortmess' option to include the flag "F" (which suppresses this info entirely).

Note: Whenever you use the bufdo function, you should restore the current buffer afterwards again. It is a bad habit to find yourself in another buffer other executing a function. This might lead to unexpected results.

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.