Suppose I want to write N words related to my studies in Vim everyday as my daily goal.

Every time I am done writing something I can do g+Ctrl-g and then I can send that number variable to a file. I want help in automating this.

If at each save vim can execute a shell command like Words diff (where Words is a bash script in my path) with diff being the word difference between the two saves, this can be automated.

The problem is that I don't know vim-script. With the basic structure of the function I think I will be able to tweak it to my needs.

Can you help?

Edit: full explanation

I imagine something like a :Write mode which sends the new added words (diff: difference between saves) on each save to a file.

Similar to this mode, I imagine an :Edit mode, which would do almost the same thing.. instead of sending the difference diff, it would send 2*abs(diff).

I use vim splits very often, so a full shell script solution which uses the only original file name can't solve my problem. For each split I would like to invoke these command functions separately.

I can do basic bash scripts, so you can leave the writing to file part to me.

  • This is also good. I am okay with bash. I was going to modify the vimscript function to make write and edit versions (as editing isn't really about adding words) but I guess I can also make two shell scripts. If I am editing a file, I would like to double the abs(wc difference). Anyway, please do put it as answer - your shell script is quite interesting. Dec 20, 2020 at 21:50
  • If its a shell script though, I cannot switch between editing and writing without quitting. Also, writing with vim splits would not be possible. I think a vim function is needed. Dec 20, 2020 at 22:04
  • I am sorry. I tried to keep it simple. I have edited my question. Dec 20, 2020 at 22:34
  • No apology necessary.
    – B Layer
    Dec 21, 2020 at 0:06

1 Answer 1


I modified this answer by Martin Tournoij to my needs.

fun! s:write() abort
     if get(b:, 'write_start', 0) is 0
        let b:write_start = wordcount()
        let l:words = wordcount()['words'] - b:write_start['words']
        let b:write_start = wordcount()
        execute !BashScript l:words

command! Write call s:write()

where the BashScript is in the path and can be as simple as

echo $num >> path/to/your/file

Now I can call :Write at the beginning to initialize the word count and thereafter, on each :Write will append the added words to my file. This can of course be made fast using a custom remap.

It's trivial to repeat this for :Edit mode now.

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.