jump over user defined text objects in vim - vim

I am using the kana / vim-textobj-user for defining some custom user objects but the problem is I can't jump over them : case in point
let's say I am using the same indent text object which is mapped by ai and ii
I want to jump around the text in normal mode something like ]i and [i
currently I am using a very hacky way of selecting and exiting visual mode
So is there a simple way to do that and have some kind of mappings for all the other user text-objects as well .
Something like ]{text-object}

I am using the kana / vim-textobj-user for defining some custom user objects
[...]
let's say I am using the same indent text object which is mapped by ai and ii
I want to jump around the text in normal mode something like ]i and [i
Vim has a bunch of built-in commands like ]m, [M, etc. So I thought you meant ]i/[i to move the cursor to the next/previous text object. If so, vim-textobj-user supports both selecting and moving to a text object since its first release. But it's not automatic. At least you have to declare what keys (such as ]i/[i) to be used for the commands.
But I wonder about the following sesntence:
currently I am using a very hacky way of selecting and exiting visual mode
So you typed like vaio<Esc> and vai<Esc>? What you want to do is to move the cursor to the first/last line of the text object under the cursor? If so, vim-textobj-user currently doesn't provide API to define such commands.
In this case, it is probably possible to automate defining key mappings like nmap ]i vai<Esc>. But it seems to be fragile and overrides several built-in commands.

Text objects are only for applying a command (e.g. gU) or visually selecting an area of text. Motions over / to the next occurrence are highly related, but different commands. I think the vim-textobj-user plugin only provides the former, but not the latter.
My CountJump plugin is quite similar, and provides commands to set up both text objects and jumps based on regular expressions.

Related

Visual selection and replacement in vim

How can I select different portions of multiple non-contiguous lines and replace them with the same/different text?
Example: Let's say my buffer looks like this-
Roses are reed,
Violets aree blue,
Sugaar is sweet,
And so are you,
I want to change in 1st line the 3rd word ('reed') to 'red, yellow and green', in 2nd line 'aree' to 'are', in 3rd line 'Sugaar' to 'Sugar and molasses' and in 4th line 'you,' to 'you.'.
Say my cursor is at 'R' of 'Roses'. I want to select all four of these wrongs at once and nothing other the wrongs. After I'm done selecting I want to be able to move to 'reed' by pressing some key (say Ctrl+j), then after changing I want to be able to press some key (say Ctrl+j) and move the next visual selection which is 'aree'.
Is there any plugin that does this?
There are multiple cursors plugins that attempt to create parallel editing functionality seen in other editors to Vim (which is difficult). If I understand your use case right, that wouldn't help here, though, because all places would be edited in the same way (so reed, areee, etc. would all be replaced with the same red).
Instead, what you seem to be asking for, is a way to search for all wrongly spelled words, and then edit them one by one, individually. You can do this with standard search, using regular expression branches:
/reed\|areee\|Sugaar\|you,/
You can then simply press next to go to the next match after you're done. Note that the branches have to be unique (so I searched for you, instead of simply ,). Adding word boundaries (\<reed\> instead of reed) is a good idea, too.
plugin recommendations
multiple cursors is a famous plugin for parallel editing
My SearchAlternatives plugin lets you add the current word under the cursor as a search branch with a quick (<Leader>+ by default) key mapping. (However, if you're already on the word, why not correct it immediately?)
My SpellCheck plugin populates the quickfix list with all misspelled words and locations. You can then use quickfix navigation (e.g. :cnext) to quickly go to each. The plugin also offers mappings to fix spelling errors directly from the quickfix list.

How to paste previously prepared code snippets in Vim?

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

VIM Delete Standard Scripting Word Groups

How would you use VIM to delete a word group, which includes white space characters, but is a standard grouping you would want to access when scripting? Specifically, when you have your cursor over some part of the following text, how would delete help="initialize, lines, h2, derivs, tt, history", from below. Maybe one would need to create specific mappings. But on the other hand, it seems pretty natural to want to access text like this if you are using VIM to edit scripting programs.
parser = argparse.ArgumentParser()
parser.add_argument("task", help="initialize, lines, h2, derivs, tt, history", default='yes')
Vim has a variety of text objects built-in, e.g. da" deletes quoted text (including the quotes; di" keeps the quotes). See :help text-objects for more information.
There are some plugins, e.g. textobj-user - Support for user-defined text objects and my own CountJump plugin that make it easy to define your own, "special" text objects. Also, you'll find many such text objects on vim.org. Based on your example, argtextobj.vim - Text-object like motion for arguments may be exactly what you need here.
If you are inside the " you want to delete, I would use:
di"diW
If you were above help=, I would use something like:
d/defEnter
to remove everything until you encounter default, followed by a few x, and left-wise motion, to remove the remaining characters.
I don't really think a new mapping is needed, but your experience may vary.
What makes sense from Vim's perspective and according to its design goals is to provide small and generic elements and a few rules to combine them in order to achieve higher level tasks. It does quite a good job, I'd say, with its numerous text-objects and motions but we always have to repeat domain-specific tasks and that's exactly where Vim's extensibility comes into play. It is where users and plugin authors fill the gap with custom mappings/object/functions and… plugins.
It is fairly easy, for example, to record a macro and map it for later reuse. Or create a quick and dirty custom text-object…
The following snippet should work with your sample.
xnoremap aa /\v["'][,)]/e<CR>o?\v\s+\w+\=<CR>
onoremap aa :normal vaa<CR>
With it, you can do daa, caa, yaa and vaa from anywhere within that argument.
Obviously, this solution is extremely specific and making it more generic would most certainly involve a bit more thought but there are already relatively smart solutions floating around, as in Ingo's answer.

Vim Visual Select around Variables

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!

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.

Resources