Is there plug-in that makes vim close syntactic constructions that wraps code blocks automatically for any language based on data in indent and syntax files?
For example I editing lua file, when I write
function myfunction()
and press enter it automatically make an closing "end"
function myfunction()
<cursor position>
end
Or maybe anyone can show an example how to write your own plug-in for specific language with long keywords for code blocks (like lua, erlang or pascal) ?
Endwise seems to be what you're looking for. It already has lua support, and it looks like it would be pretty easy to extend, if you are comfortable with VimL.
I would use a snippet plugin like UltiSnips (my favorite) or Snipmate. They essentially expand some small word or piece of text into larger pieces of code and allow you to edit only the parts that are unique for each structure. Both UltiSnips and Snippmate include snippets for many languages and let you create your own snippets.
For example UltiSnips inclueds a function snippet for Lua. I just have to type out fun and then press tab and it gets expanded to
function new_function(args)
end
and new_fuctnion gets selected so I can edit the function name. Then once I press Ctrl-j (in my vimrc I rebind this to Tab) it selects the next part of the snippet which is args in this case allowing me to enter the function's arguments. A final Ctrl-j puts the cursor in the body of the function.
Related
I am new to Vim and I need to speed up my typing for this kind of statements.
if (a == 'e') {
foo();
}
In other text editors, I usually type if() {} first and then insert the text in to the parenthesis and curly braces. If I do this in Vim, I need to switch back to normal, move cursor to middle of () then middle of {}... switch between i and esc ...
What is your suggestion on typing this kind of syntax for Vim beginner? I would be grateful if you can show me the commands for that example step by step.
This is a job for snippet expansion. Take a look at SnipMate or UltiSnips.
snippets are like the built-in :abbreviate on steroids, usually with parameter insertions, mirroring, and multiple stops inside them. One of the first, very famous (and still widely used) Vim plugins is snipMate (inspired by the TextMate editor); unfortunately, it's not maintained any more; though there is a fork. A modern alternative (that requires Python though) is UltiSnips. There are more, see this list on the Vim Tips Wiki.
There are three things to evaluate: First, the features of the snippet engine itself, second, the quality and breadth of snippets provided by the author or others; third, how easy it is to add new snippets.
There are two approaches that solves your goal:
abbreviations
and snippets engines
Abbreviations and the old way of doing things. You just type if and space, and tada! You'll find plenty examples around the web. Only a few will be context-sensitive (i.e. they won't expand within comment or string contexts), or able to take the current project spacing style into consideration. In lh-cpp, you'll find the usual control-statement abbreviations for C and C++, they'll need to be duplicated for similar languages (a runtime ftplugin/c/c_snippets.vim from a php ftplugin should do it in your case)-- in lh-misc I support a couple of others languages (for VimL and shell)
Snippet engines are the trendy way of doing the same thing. This time, you will be able to type i or if and then <tab> (or CTRL+SPACE, or ...). Control-statement snippets won't need to be aware of the current context as we need to explicitly require the expansion. Others have already given links to the trendy snippets engines. Snippets from lh-cpp (which relies on mu-template) take the project style into account when expanding control-statement snippets (i.e. some projects want ) and { on a same line, other want a newline in between, ...)
Here's my answer in case you want to go with vanilla Vim.
In the majority of the cases I guess there is no point in entering the parentheses first and filling in the condition later, just type it all in right away:
if (a == 'e')
Then you can either continue
by typing {}<ESC>:
if (a == 'e') {}
^ cursor is here
The cursor is already placed so you can continue with i<CR> and type the body (if properly configured, Vim should indent for you).
or by typing {<CR>}<ESC>:
if (a == 'e') {
}
^ cursor is here
Then you can enter the body by pressing O (open new line above cursor). Possibly Vim also automatically indents here (it doesn't in my configuration).
If you really want to fill in the condition after you have entered this:
if () {
}
^ cursor
you can do so by typing kf(a.
If anybody knows better ways to do this without plugins, suggestions are welcome.
In Windows, using the AutoHotkey utility, it's possible to write simple scripts to expand some text in an editor of choice (e.g. Visual Studio's editor).
For example, if in Visual Studio editor I type:
d1 [TAB]
(i.e. press the keys in sequence: d,1,Tab) the above "d1" text can be replaced with one or more lines of code snippets. The mapping between "d1" and the expanded lines of code is specified in a AutoHotkey script.
This is very convenient e.g. for demos; for example: at some point if I'd like to enter a whole function body, assuming that I associated it to e.g. "d3", I can simply press d3Tab on the keyboard, and I get the function body automatically pasted in the editor in current cursor location; and I can have different code snippets associated to different key combinations, e.g.
d1 --> DoSomething() function definition
d2 --> class Foo definition
d3 --> test code xyz...
Is it possible to achieve the same goal using Vim?
In other words, I'd like to have a set of code snippets previously prepared, and I'd like to paste each one of them in my currently edited source code file in Vim, in a way similar to what I described above.
Basic expansion can be done via the built-in abbreviations, for example:
:inoreabb d1 DoSomething()<CR>{<CR><CR>}<CR><Up><Up>
Read more at :help abbreviations.
snippets are like the built-in :abbreviate on steroids, usually with parameter insertions, mirroring, and multiple stops inside them. One of the first, very famous (and still widely used) Vim plugins is snipMate (inspired by the TextMate editor); unfortunately, it's not maintained any more; though there is a fork. A modern alternative (that requires Python though) is UltiSnips. There are more, see this list on the Vim Tips Wiki.
There are three things to evaluate: First, the features of the snippet engine itself, second, the quality and breadth of snippets provided by the author or others; third, how easy it is to add new snippets.
I have previously used snipMate that does something like what you're describing.
http://www.vim.org/scripts/script.php%3Fscript_id%3D2540
[Edit: after reading comments I realize that the Surround plugin is adequate for my needs after all, so I'll leave this question for purely academic purposes to gain a better understanding of vimscript's inner workings]
I'd like to make adding/deleting tags, quotes, braces, and other symmetrical text structures easier to do in Vim, and I find the surround.vim plugin a little too quirky and specialized for my needs.
What I really need is more generally a "mirrored" input mode and "mirrored" deletion mode, whereby I could visually select a block of text, then type onto or delete from both ends of the selection at once. As an example workflow, I'd like to:
select the word hello
hit some keystroke combo to enter "mirror mode"
type "
my text now says "hello"
In this example I only typed one character at each end, but it's important that in step three I could have typed many characters, not just one, for instance I should be able to type <b> to produce <b>hello<b> (I still would need to manually add the / in the closing tag, which I'm OK doing).
So is this even possible in Vim? Could someone provide a broad outline of functions that would be involved in the solution? Specifically, I don't know how to intercept text as it's being inserted and then alter the location where it appears so that it's tacked onto the beginning and ending of the selection block instead of the cursor location. And ditto for deletion.
Well, the behavior you describe is exactly what Surround does:
select the word hello
hit S
type "
my text now says "hello"
The difference with what you ask is the "live updating" or "live mirroring" which I have no idea how to do. You could probably take a look at SnipMate or UltiSnips for that part.
I'm wondering if there's a way to select variables intelligently in the same way that one can select blocks using commands like va}. There's some language-specific parsing going on to differentiate php and ruby, for example. For future reference, It'd be nice to tap into that - ideally selecting around various syntactic elements.
For example. I'd like to select around $array['testing'] in the following line of php:
$array['testing'] = 'whatever'
Or, lets say I want to select the block parameter list |item, index| here:
hash.each_with_index { |item, index| print item }
EDIT:
Specific regexps might address the various questions individually, but I have a sense that there ought to be a way to leverage syntactic analysis to get something far more robust here.
Though your given examples are quick to select with built-in Vim text objects (the first is just viW, for the second I would use F|v,), I acknowledge that Vim's syntax highlighting could be a good source for motions and text objects.
I've seen the first implementation of this idea in the SyntaxMotion plugin, and I've recently implemented a similar plugin: SameSyntaxMotion. The first defines motions for normal and visual mode, but no operator-pending and text objects. It does not skip over contained sub-syntax items and uses same color as the distinguishing property, whereas mine uses syntax (which can be more precise, but also more difficult to grasp), and has text objects (ay and iy), too.
You can define your own arbitrary text objects in Vim.
The simplest way to do custom text objects is defining a :vmap (or :xmap) for the Visual mode part and an :omap for the Operator-pending mode part. For example, the following mappings
xnoremap aC F:o,
onoremap aC :normal! F:v,<CR>
let you select a colon-enclosed bit of text. Try doing vaP or daP on the word "colon" below:
Some text :in-colon-text: more of the same.
See :h omap-info for another short example of :omap.
If you don't mind depending on a plugin, however, there is textobj-user. This is a general purpose framework for custom text objects written by Kana Natsuno. There are already some excellent text objects written for that framework like textobj-indent which I find indispensable.
Using this you can easily implement filetype-dependent text objects for variables. And make it available for everybody!
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"));