I have a blank .vimrc
file. I'm seeing some very strange behavior. Here's what happens:
- I open a file in vim
- I do
:split .tmp/file
and:q
- I make a change to the open file and
:w
- I run
:e #
which brings up the alternate file opened in step 2 and then swap back to first file with:e #
without doing anything else. - I run
gx
, a command from plugin I wrote (see below) that gets input from the user from vim's status bar which then passes it to a perl script. The perl script appends and writes two lines and the message to the.tmp/file
. - THE PROBLEM: When I reopen the
.tmp/file
, there are three newlines after the last message instead of two. So somehow, vim is slapping an extra newline character into my.tmp/file
.
Note: This problem does not happen when I do not run steps 2, 3, and 4; everything works as expected with two lines appended after each message. Here is my plugin (yeah, it's poorly written, it's my first one):
nnoremap gx :call AddCommNote()<CR>
let g:Msg = ''
function! AddCommNote()
call inputsave()
let g:Msg = input('Make commit message: ')
call inputrestore()
let g:Msg = call substitute(g:Msg, '\n', '', '')
let is_commit = 0
call ProcessMsg(is_commit)
endfunction
function! ProcessMsg(is_commit)
let escaped = substitute(g:Msg, "'", "'\"'\"'", "")
let command_to_run = "add_comm_note '" . escaped . "' "
let command_to_run = command_to_run . "'" . expand("%:p") . "' " . a:is_commit
exec "silent:!" . command_to_run
:redraw!
endfunction
I've stripped all newlines from g:Msg
in the plugin and in the perl script. The newline is definitely coming from vim as far as I can tell. I have no idea how.
Here is the simple perl script which is in my ~/bin directory:
#!/usr/bin/perl
use strict;
use warnings;
use File::Util;
my $f = File::Util->new();
my $message = $ARGV[0];
$message =~ s/\n//g;
my $file = $ARGV[1];
my ($path) = $f->return_path($file);
my ($name) = $f->strip_path($file);
my $tmp_file = $path . '/.tmp/' . $name;
my $newlines = $f->existent($tmp_file) ? "\n\n" : '';
if ($ARGV[2] && !$message && !$newlines) {
$message = 'this commit message is unhelpful';
}
exit if (!$newlines && !$message); #nothing to add to the commit message file
$f->write_file('file' => $tmp_file, 'mode' => 'append', 'content' => $newlines . $message);
g:Msg
because you didn't pass theg
flag to thesubstitute()
function:let g:Msg = call substitute(g:Msg, '\n', '', 'g')
. Also, it could help future readers if you removed from your code everything that is not related to your issue. I didn't read the code very long, but it seems that the only relevant parts are thegx
mapping, theAddCommNote()
function and theProcessMsg()
function.add_comm_note
?), and showed what is its contents. FWIW, when I have a weird bug, usually I create a dedicated branch with git to not mess the original code, then I delete as much code as I can until the bug disappears. Usually, once you've reached the minimum amount of code to reproduce a bug, it's easier to understand it.:e #
. I should also add that every once in a while (like one out of 10 times), no extra newline gets added. So it seems like some kind of race condition going on.