Is there a "verbatim" mode for the vim map command? - vim

I am trying to set up some useful coding templates in vim, for example I have mapped
map `cl iclass <+CLASSNAME+><CR>{<CR><Esc>Iprotected:<CR><+PROTECTED MEMBERS+><CR><Esc>Ipublic:<CR><+PUBLIC INTERFACE+><CR>};<CR><++><CR><Esc>3kv<0v3k<2k
so that when I type `cl in vim I get
class <+CLASSNAME+>
{
protected:
<+PROTECTED MEMBERS+>
public:
<+PUBLIC INTERFACE+>
};
<++>
(so that I can jump between the <+ +> tags with C-j). This works fine, but I find the above remap pretty obscure. Is there a way to enter what I want vim to type in "verbatim mode"? So I would want to write something like
map `cl i{VERBATIMSTART}class <+CLASSNAME+>
{
protected:
<+PROTECTED MEMBERS+>
public:
<+PUBLIC INTERFACE+>
};
<++>{VERBATIMEND}
?
Thank you
Paul

I don't know if there is such a "verbatim"-mode for mappings.
I, personally, would use one of the snippet-plugins to do this.
See www.vim.org and search
for "snippet". I have not tried all of them (just SnippetsMgr ;-) ),
but I suppose that they are handier to define multi-line-snippets.
Some of the available snippet-plugins on vim.org: snippets.vim ,
snippetsEmu, snipMate, SnippetsMgr, etc.

As Habi has mentioned, one way to go about this is with a snippet plugin.
Another way is to copy that snippet of code into its own file and set up your mapping to insert that file below the cursor:
map `cl :r /path/to/code_snippet<CR>

Kind of obvious (and probably not what you want) is:
map `cl iclass <+CLASSNAME+>
\<CR>{
\<CR>protected:
\<CR> <+PROTECTED MEMBERS+>
\<CR>public:
\<CR> <+PUBLIC INTERFACE+>
\<CR>};
\<CR><++>
\<CR>
\ in beginning of line tells that the line is the continuation of the previous one. But this is rather literal continuation: it doesn't add new lines so one has to add them manually. Since it uses the insert mode, the operation would be also affected by the current indentation mode. (Though one can try to work that around with :set paste/:set nopaste.)
I would have tried to put the text into a temp variable or register then Pput (or :put) it into the buffer. E.g. setreg() allows one to tell that the content of a register are lines and thus Putting it would work regardless of indentation.
Otherwise, looking in :help line-continuation or :help variables I see no way how one can specify a multi-line string or text.

Related

How to create a macro with vim commands?

I am trying to create a macro to use it globaly. I have inserted this command to my .vimrc file
let #c='<esc>:r c.c'
or
let #c=':r c.c'
but in both cases when I use "#c" on any file it only prints 'c>:r c.c' on the the file
Try adding a '^M' at the end of your macro, then "#c" should work. Else ':#c' should work as mentioned by ebenezer. You should use Ctrl+VEnter to insert '^M'.
let #c=':r c.c^M'
Best way would be to record the macro first and then save it to the .vimrc.
If these doesn't work, you can check the content of your register c using "cp and see if there is something missing.
This is described in another answer. Try something like this:
let #c = ':r c.c'
and then, in your file, use
:#c
to execute it.
If you want to include special characters in your macro (like Escape or Enter) then use a non-literal string (double quotes, not single quotes) and the correct syntax. See :help expr-string. You could use raw special characters, as #Amit suggests, but this will make your vimrc file hard to read.
Assuming that you are starting in Normal mode and want to type #c, there is no need to start off with an Escape.
For testing purposes, I tried
:let #c = ":echo 'foo'\<CR>"
and it worked as expected. I even added this line (without the leading :) to my vimrc file just to make sure, and tested it that way. This should work:
:let #c = ":r c.c\<CR>"

How to commentize a word in Vim?

I would like to commentize a word under the cursor and use it as a macro or map it as a key binding.
For example this:
void somefunc(MyType* pType);
Would become:
void somefunc(MyType* /*pType*/);
I know that I just need to prepend and append word with /* and */ but I dont know how to do this.
try either of this mapping, pick one you feel better.
nnoremap <leader>cw caw/*<c-o>P*/<esc>
or
nnoremap <leader>cw viw<esc>a*/<esc>hbi/*<esc>
type <leader>cw in normal mode.
A way more general way to create inline comments is to use the Tcomment plugin.
When you've installed it you can use the gc operator to comment something, for example if you have the following file (with ^ indicating the cursor):
void somefunc(MyType* ^pType);
Pressing gce will get you:
void somefunc(MyType* /*pType*/);
You can use this for any motion command, but of course a line wise operator (eg. gcj) will not comment inline but entire lines instead.

Vim macro: log/variableize selected object

Is there some sort of Vim plugin that would allow me to do something like this, given the code:
function something (arbitraryObject) {
arbitraryObject.something = doesNotMatter;
}
Then let's say I just select the word arbitraryObject in the function body, I'd like an easy way to write a macro that, given a short key combination or command-mode command, could give me something like:
function something (arbitraryObject) {
arbitraryObject.something = doesNotMatter;
console.log(arbitraryObject);
}
or...
function something (arbitraryObject) {
arbitraryObject.something = doesNotMatter;
window.arbitraryObject = arbitraryObject;
}
Note that I'm not asking what this macro would actually look like, I'm curious if there are built-in tools or plugins that make the creation of things like this particularly easy.
I know that you aren't asking for the specific macro, but it's easiest to learn these types of things by example. The first one (console.log) can be achieved through this mapping:
:vmap <leader>il y<esc>oconsole.log(<c-r>");<esc>
Likewise, the second one could look like this:
:vmap <leader>iw y<esc>owindow.<c-r>" = <c-r>";<esc>
Can you spot the similarities? <leader>il means that the command binds to the leader key (usually ,) followed by i followed by l. You can check what the following commands mean by using :help [key] in vim, but the mappings basically yank (copy) the selected text, enters a new line (Esc, o) and then appends some text followed by Ctrl+r and ", which inserts the yanked text.
One option would be to use something like snipMate.vim and have snippets for your various tasks. For example, you could create these snippets:
snippet cons
console.log(${1:variable});${2}
snippet wind
window.${1:attribute} = $1${2}
Then you could do something like yocons<Tab><C-r>"<Tab>, or likewise yowind<Tab><C-r>"<Tab>. You could also use yiw instead of visually selecting too. I like an option like this because then you can easily make it applicable to only a particular type of filetype (e.g. javascript) and continue to extend your already existing snippets.
nmap <Leader>l o<esc>pv^"xygv[ygvdiconsole.log(<esc>a"<esc>pa",<esc>"xpa);<esc>
This is better alternative, since it quotes strings with help of vim-unimpared. Just yank text, you need to log and use this key binging. It converts
this.$el.find("input,select,textarea")
to
console.log("this.$el.find(\"input,select,textarea\")",this.$el.find("input,select,textarea"));

Delete surrounding whitespace in vim

I'm using the awesome https://github.com/tpope/vim-surround plugin to surround words with parenthesis, for example I often use: viws<space><space> to surround a word with spaces.
What I'm missing is the opposite of this, that is, deleting surrounding spaces around a word.
The most common use for me is function arguments like
foo(bar) vs foo( bar ) depending on code style.
Does anyone know a nice way to do this?
Note: This solution requires the surround plugin referenced in the question.
For your specific situation you could do the following:
cs()
This changes foo( bar ) to foo(bar), however, it is not a general solution to your problem.
I often productively procrastinate in search of vim plugins too, when I could just define a mapping for this.
nnoremap <leader>dd F<space>xf<space>x
EDIT more information
<leader> common key for user defined mappings (, is a good one)
dd combination to use (any other mnemonic one will suffice)
F<space>x search backwards for a space, then remove it
f<space>x search forwards for a space, then remove it
Maybe just BXElx in normal mode.
In fact, perfect solution for me is the mapping provided by #puk, but using the keys #sarnold expected in the first place (what one would expect from surround plugin if it implemented this).
This is:
nnoremap ds<space> F<space>xf<space>x

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

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.

Resources