Does Vim have an auto-comment feature based on the file's syntax? - vim

I'm not sure this is possible, but I'm interesting in making this happen.
Ideally, I would like to map this feature to SHIFT+CTRL+3.
I'm looking for a way to have Vim enter a comment (single line) which corresponds to the syntax of the file I'm editing. If there are multiple single-line comment styles, Vim could either automatically pick one, or give me the choice. If the single-line comment has two parts (e.g. /* and */), then pressing SHIFT+CTRL+3 the first time will start the comment, and the second time will close the comment.
Examples:
Python: #
JavaScript: //
C, C++: /* with */ or //
I know there are scripts which will insert comments for you, but I haven't seen any that will do this based on the syntax of the file.

I highly recommend NERD Commenter.

Sort of! I don't believe vim will do this out of the box, but you can install plugins that will do fairly intelligent commenting (using movement keys, visual line highlighting, etc) that are specific to the filetype being edited. You can get these plugins off of vim.org, and you should be able to make your own key mappings in your .vimrc file if you don't like the ones they come with.
tComment is pretty well regarded, and has worked for me.
I've heard that EnhCommentify might be better, but I haven't used it myself.

Seems like a similar question to this:
How to comment in vim while respecting the indent?
Use the nerd commenter plugin:
http://www.vim.org/scripts/script.php?script_id=1218

See: this script which provides a function to commented a highlighted area in visual mode.
You want to start a comment in insert mode so your function would look more like:
fun CommentLines()
exe ":s#^#".g:Comment."#g"
endfun

Not quite what you're looking for, but efficient, and I suppose you know which comment to use.
(all this in command mode)
Put your cursor to the first line you want to comment. We willl then set a marker called a (valid names are a-z, single character) by typing
ma
put the cursor to the last line, then set a marker called b by typing
mb
Then comment the whole block (by searching for a newline and inserting the comment character (note the use of "#" as search delimiter because otherwise wee have to escape the "/")
:'a,'bs#^#//#
or for Python:
:'a,'bs/^/#/
To uncomment:
:'a,'bs#^//##
As we do line comments, it doesn't matter if we have other comments already in the file, they will be preserved.

Related

How can I add /* at the beginning and */ at the end of a line in Vim?

I want to do something like commenting a line like follows,
/*commented line*/
How can I do it? Is there any short cut command to achieve this task?
There's no built-in command (even though Vim has a 'commentstring' option to define the syntax). Toggling comments is a solved problem; don't try to invent your (poor) alternative. The most popular plugins (that I know) are:
The NERD Commenter
EnhCommentify.vim - comment lines in a program
tComment - An extensible & universal comment plugin
commentary.vim : Comment stuff out; takes a motion as a target
You can use :s/^\(.*\)$/\/*\1*\//.
If you want to create a macro, then something like qa^i/*<ESC>A*/<ESC>q associates to the name a the commands that comments the current line. If you want to use the macro you can type #a.

some simple vim commands

sorry if this isn't exactly a programming question.
I mainly use Vim to edit my programs. So my question to all the Vim experts out there is:
is there a way to select and scroll in Vim? I want to copy a bunch of code, and in the pass I have always copied everything I can view on the vim screen then paste it to where-ever, then scroll down then copy and paste..repeat..until done. Is there a way I can efficiently copy a large block of code?
Formatting lines of code- you know when you copy and paste some code sometime 10 lines of code turn into 30 really messy lines of code? well, is there a command to reformat the code? In the pass I manually go back and properly indent everything which sometime is super repetitive when you got 500 lines. I saw on other sites something about the command being 1G = G can someone confirm that? when I try it in my command line, I get a error E464: ambiguous use of user-command line which I have no idea what that even means.
I do know there is a help command in Vim,but I have no idea where to even start when there is something like 200 txt files and frankly this is faster :)
Your questions are around basic use of vi / Vim. Do yourself a favor and go through a Vim tutorial; you'll find many on the web, and Vim comes with it's own introduction, vimtutor.
On Unix, if Vim has been properly installed, you can start it from the shell:
vimtutor
On MS-Windows you can find it in the Program/Vim menu. Or execute
vimtutor.bat in the $VIMRUNTIME directory.
Also, learn how to look up commands and navigate the built-in :help; it is comprehensive and offers many tips. You won't learn Vim as fast as other editors, but if you commit to continuous learning, it'll prove a very powerful and efficient editor.
The vim way is to entirely forget selection using the mouse for more than a screenful, but to set a mark, move to the other end of the desired text, then yank to mark:
Set mark m at beginning of text with mm
Move to end of text
Yank to mark with y'm
Paste with P or p
This whole answer is only helpful if you can use register + as clipboard. Try "+yy in VIM, try to paste it in another application to see if you can use the clipboard, if you can:
You should really read the manuals and other help:
To yank lines (simple) : http://vim.wikia.com/wiki/Moving_lines_up_or_down
To address lines: Addressing in VIM
That is to start with.
Some examples of what you can do:
:.,+50y a yank 50 lines from current and 50 ahead to register a, use A instead to append to register A.
:.,/some pattern/y A yank (append) from current to first line that match /some pattern/ to register a.
"Ay/some pattern<CR> will do the same thing.
Once you learn how you should address, it's easy to combine commands with addressing, e.g. the "indenting command" =:
=} auto indent to the end of current paragraph
=/some pattern<CR> auto indent to line matching /some pattern/
Mark something in Visual mode and type = it will auto indent the selected text.
And so on... So read manuals, you will have a great use of it.
In the above examples you can use register + to "yank" to the clipboard instead of register a.

VIM: Respect only current code block

I have started working on a huge PHP application that has thousands of lines of code in each file, with lots of huge if blocks, classes, and functions all existing in the same file. I'm not the only dev working on it, so I cannot refactor!
I have tried using the Tags List plugin but it does not really help. Is there any way to have VIM respect only a particular code block, and ignore the rest of the file? I am hoping for some or all of these features:
Enable line numbering only for the current code block, starting from 1 at the line containing the opening {, and showing no numbering for lines preceding it or after the closing }.
Searching with / would be restricted only to the block in question.
I am thinking along the lines of selecting the current block and editing it in a new buffer when enabling the mode, then replacing the existing block with the edited block when exiting the mode. However, I am having trouble actually implementing this feature. My current version is this:
map <F7> <Esc>mO<C-V>aBy:new<Return>p:set nu<Return>:set ft=php<Return>ggi<?php<Return><Esc>
map <F8> <Esc>ggdd<C-V>aBx:bp<Return>`O<C-V>aBp
However, this has several issues, such as the inability to perform incremental saves.
I would be very surprised if Vim allows the kind of line numbering you ask for.
This plugin (and 1 or 2 similar ones IIRC) allows you to visually select a region of your current file, work on it in another buffer and put everything back in its place in the original file on :w.
Even if it's not the solution you are wanting, I think the following can help you to solve your problem.
You can use phpfolding plugin, which folds by PHP syntax (functions, classes, methods, PhpDoc...)
You can then select a fold by pressing v$ over the closed fold and execute whatever you want with :whatever. For example, :s/this/self/g to substitute all this for self in the fold. When you press :, vim will automatically add '<,'> to denote following command it's only for the visually selected text.

Nicely formatting long //comments in vim

When I am typing a long code comment in VIM, I manually judge when each comment line reaches 80 characters, then manually typically press < enter >< tab >//< space > and continue on. Likewise it is awkward editing comments, adding or removing text.
// The comments I have to use
// look like this
Ideally, I'd like some kind of comment mode, where you type text, and the 80 line character limit and the // symbols are sorted out automatically. Does anything like this exist?
You can turn on formatting options with set formatoptions=tcq (with tcq each representing an option, there are others as well). Use h formatoptions to see what the various flags are.
In this case you probably want to use set fo+=a.
Personally though, I prefer to just type my comments normally, then when I'm done run gqip. gq is the formatting command, ip for in paragraph. Make sure the comment block is not next to code though or it will suck that up when reformatting your comment.
I use :set textwidth=80 to set the formatting width (actually, 80 is the default).
Then I move the cursor to the first line of the comment and in command mode press gq} to format the comment. It also works for other comment types from other programming languages such as # and /* ... */
A variant on #Alex's suggestion is to select the lines in visual mode and then press gq. This allows you to avoid the problem of gqip reformatting code as well.
Pressing capital V selects an entire line, then you can just move up or down to highlight all the comments and press gq.

Vim Surround: Create new tag but don't indent/new line

I would like to mimic Textmates CTRL+ALT+w, which creates a new pair of opening and closing HTML tags on the same line.
In VIM Surround I'm using CTRL+st in Edit mode for this, but it always indents and creates a new line after setting the tag, so that it looks like this (* = cursor position):
<p>
*
</p>
Is there a way to achieve this? :
<p>*</p>
I guess your problem is that the selected area is "line wise". For example, if you select a few lives with V and surround it with tags, the tags will be placed one line above and one bellow the selected lines.
You probably want to create a "character wise" selection, with v before surrounding it.
Anyway, please post the map you created, so we can help debugging this.
Update
After some clarification in the comments, I would tell you that the surround plugin is not the best option. As its name describes, it was created to deal with surrounded content. So you may need content to surround.
In your case, I recommend taking a look in HTML AutoCloseTag. This plugin closes the html tag once you type the >. It is certainly more appropriated, and uses less keystrokes than surround.
<p <--- Now when you type ">", if becomes:
<p>|</p> <--- Where "|" is the cursor.
Obviously, you will get this behavior to every tag. But that may be handy if you like it.
From normal mode, type vstp> to enter visual mode and output an opening and closing <p> tag on the same line at the current cursor position. Use a capital S to maintain the current indent level.
This doesn't place the cursor in between the tags as you describe, but neither does Textmate's CtrlW shortcut (I think you meant CTRL+Shift+w, not CTRL+ALT+w, as the latter just outputs a diamond sign.)
My answer is probably coming to late, but I'll try to help.
I had similar problem with Vimsurround plugin. Every time I select sentence (one line) using ctrl+V and try to surround it with something I get this:
{
var myVar
}
instead of this:
{ var myVar } // what I wanted
I found easy solution: From a normal mode I choose a line with vis command and then I type capital C (my vim surround mapping ) and choose brackets to surround.Then I get one line nicely surrounded.
The question title is technically mislabeled based on what the author was actually looking for, but since I was actually looking for the answer to the question asked in the title, I figure I should provide an answer to it as well.
To create a new tag surrounding an element without the automatic indentation Vim Surround uses when using a block wise selection (ie: VysS), you can instead do something like:
^ys$
This command will move your cursor to the first non-blank character of the line, issue the command that you want to utilize You Surround, and move to the end of the line. Then, simply start entering your tag.
The result is this:
<input type="email" name="email">
Could become something like this:
<li><input type="email" name="email"></li>
The command is repeatable as well with . and all the normal other Vim goodness.
Stumbled upon this question because I was wondering this as well - I believe the simplest way to do this is just:
yss<p>
(yss surrounds a line with something without indenting - see here: http://www.catonmat.net/blog/vim-plugins-surround-vim/)
You can accomplish this by selecting the relevant text object: :h text-objects
...and surrounding that instead of surrounding a Visual Line selection.
The most common example I found myself running into was when trying to surround one tag with another. In that situation, the it and at text objects are quite useful:
*v_at* *at*
at "a tag block", select [count] tag blocks, from the
[count]'th unmatched "<aaa>" backwards to the matching
"</aaa>", including the "<aaa>" and "</aaa>".
See |tag-blocks| about the details.
When used in Visual mode it is made characterwise.
*v_it* *it*
it "inner tag block", select [count] tag blocks, from the
[count]'th unmatched "<aaa>" backwards to the matching
"</aaa>", excluding the "<aaa>" and "</aaa>".
See |tag-blocks| about the details.
When used in Visual mode it is made characterwise.
For example, if you had your cursor in a paragraph and you wanted to surround it with a div on the same line, ysat<div> would accomplish that.

Resources