6

I am very new to vim and would like to know if I could have a script in my vimrc file that automatically adds a ; to the end of every line.

The only exceptions is if the line has the strings for(, while(, #include, //, /*, */ etc.

I would like this to be turned on by default and toggled on and off via the shortcut Ctrl+;.

8
  • 7
    I would suggest that you learn to program C (or C++, Java, Javascript) better. There are many cases where you do NOT want to add a ;, for example when breaking a function call with many arguments over 2 or more lines... Scripting all of these cases is difficult... You will quickly get used to adding the semicolons, so just hang in there for a little while :-) Mar 3, 2015 at 18:13
  • Thanks for the tip. I know about that which is why I put etc. in my exceptions. This is also why I want to toggle it on and off.
    – iProgram
    Mar 3, 2015 at 18:18
  • 2
    Expanding on @Carpetsmoker's comment, beware that automatic ; insertion could even be dangerous if it is not perfect (and no code is perfect). Imagine the following confusing set of lines: if (this > is followed by && a + /* check */ followed by that * is_very(important | followed by security | wise)) followed by do_something();. If your automatic ; insertion makes a mistake and puts a ; at the end of the if, then you immediately get a hard-to-detect security bug.
    – Shahbaz
    Mar 6, 2015 at 13:23
  • 1
    Furthermore, sometimes this is even impossible to know without actually trying to compile the code. Imagine someone doing this for whatever strange reason: #define UNTIL(x) while (!(x)). Then when you write UNTIL(out_of_bounds), it's impossible to know if that's a function call and therefore needs a terminating ; or a macro that expands to while and therefore doesn't need a terminating ;. If you do insert the ;, you are in trouble.
    – Shahbaz
    Mar 6, 2015 at 13:29
  • 2
    In short, if it were possible to unambiguously understand where there should be a ;, they wouldn't have added ; to the language now, would they? ;) Since that's not possible, you can't have a program that correctly inserts it for you either.
    – Shahbaz
    Mar 6, 2015 at 13:31

2 Answers 2

6

As has been stated, your list of exceptions is by no means comprehensive and you will probably find that this often creates more problems than it solves.

However, it's still doable and it was kind of fun to write out the code to do so, so here goes:

"When hitting Enter, if the line doesn't start with a /*, insert a semicolon
:inoremap <CR> <C-R>=match(getline('.'), '\s*/\*')==-1?';':''<CR><CR>

Feel free to expand this regex to capture your conditions above. I didn't want to write all of that out as I feel like it would obfuscate what I was writing and would still not be a complete solution for what your intent is.

You would probably want to only do this for certain filetypes, in which case you'd want to add the <buffer> argument to this command and do it inside an autocmd Filetype block.

To disable the mapping, you would say :iunmap <CR>

11
  • 1
    You can't add blank lines now :-) ... There are probably many more situations where this will do unexpected things ! Mar 3, 2015 at 19:55
  • 1
    Yep, that was the first thing I noticed too. It will also add a semicolon even if the line already has a semicolon at the end of it and fail for many other instances where the end of a line is not the end of a statement. I really hope the code I use above is not used by someone for semicolon insertion, but maybe it will help someone apply these tricks to a different use case. If someone adds enough exceptions that they truly feel that automatic insertion improves their workflow, then good on them.
    – Matt Boehm
    Mar 3, 2015 at 21:24
  • On a related note, I sometimes find myself accidentally adding semicolons in python, so I do inoremap ; _ for those files. Gives me a slightly easier way to type underscores, but when I do type a semicolon at the end of a line, I notice the character change and instantly catch my error.
    – Matt Boehm
    Mar 3, 2015 at 21:26
  • 2
    @Carpetsmoker thank you for pointing this out. Also thank you @_MattBoehm for giving me the starter code. Looks like I will need to add the new line exception too! Looks like a fun challenge! Looks like I will learn vim code and c++ the dame time. Challenge accepted! Will try code tomorrow.
    – iProgram
    Mar 3, 2015 at 21:30
  • 1
    You can either try to expand the pattern to match more cases or change match(...)==-1 to ((match(...)==-1) || (match(...)==-1)). Instead of ||` you may have to escape them as <BAR><BAR>.
    – Matt Boehm
    Mar 3, 2015 at 22:44
3

I think what you really want is an automatic syntax checking. Try Syntastic. The plugin shows you syntax errors so you don't have to go back and forth to the compiler to catch syntax issues like missing semicolons.

1
  • I have +1ed your comment since it is useful to know however I have not marked this as the answer because it is not automatically adding a semicolon to the end of the line. Thanks for the suggestion though.
    – iProgram
    Mar 6, 2015 at 17:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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