Vim - searching within braces - search

In vim is it possible to limit searching ONLY within closing braces?
For example.
int main() {
...
...
...
for (...) {
<><>
<><>
}
return 0;
}
Therefore for a search in the ... lines should search the entire code.
However, a search in the <><> lines should only search within the for loop.

First do the selection with vi{. Then press Esc to discard it. Then press / key to start searching. Prepend your search pattern with \%V to restrict the scope of search to previously selected visual block.
Sources:
i{ is a text object of inner brace block. Here's a nice tutorial on text objects.
and here's more about search & replace in visual selection

Just use vi{ to select text inside the braces before searching from the visual mode.

Related

VIM - how to delete all lines inside a php tag?

I would like to know how to delete :
all of the contents inside a php tag using vim
<?php i want to delete this ?>
If your opening & closing PHP tags (<?php ... ?>) are in the same line, you can do it this way.
Put your cursor at the first character after PHP opening tag.
Type v/ ?[enter]d in normal mode.
The 2nd point means to enters visual mode ('v') from the first character, searches ('/') for the [space]? (' ?') pattern (exactly before the PHP closing tag), and then delete it ('d').
Use di< or di> to delete all the characters inside <>. The cursor should be inside of the <>.
Use ci< or ci> to delete and be in insert mode.
Helpful but Optional Explanation:
It is better to start with text-objects. Excerpt from :h text-objects, given below, suggest two forms i and a
This is a series of commands that can only be used while in Visual mode or
after an operator. The commands that start with "a" select "a"n object
including white space, the commands starting with "i" select an "inner" object
without white space, or just the white space. Thus the "inner" commands always select less text than the "a" commands.
text-objects are useful to other character pair like (), {}, etc. For example, it is useful while changing
if ( i == true ) {
}
to
if (_) {
}
by using ci( or ci).

Substitute for vim replace in Sublime

I'm looking for a replacement for vim's "replace with character" command--specifically, I want to be able to select some text and replace each character with some character that I type (difficulty: No "vintage" mode)
Example:
Starting with
I am some text with an arbitrary number: 12358998281
I want an easy way to select 12358998281 and turn it into 99999999999, to make the result
I am some text with an arbitrary number: 99999999999
(in vim, this would be done by moving the cursor to the beginning of 12358998281, selecting with ve, then pressing r9)
I can do this by selecting the text, bringing up the "find" dialog, making sure "in selection" and "by regex" are enabled, searching for ., then typing my character into the resulting multiselect. This is incredibly laborious, however, and it prevents me from doing this process on a multiselect (for example, if 12358998281 exists in multiple parts of the file, I might want to quickly replace all instances of it with 99999999999, rather than performing the process above, getting the substitution, copying it to the clipboard, and then replacing with that).
Does Sublime have a command that acts like vim's "replace" that I can bind to something, or do I have to write a macro to get what I need? Or, am I approaching this from entirely the wrong direction?
A more generalized way of thinking of this is "how can I break a select into a multiselect on all characters", if that helps.
By using this package https://sublime.wbond.net/packages/RegReplace you can create regex patterns and bind them to shortcuts.
Also if there are multiple occurrences of one word, you can put cursor on whatever part of the word and press CTRL+D multiple times. One CTRL+D press will select the word under the cursor, every other press will select next occurrence of the word.
You could also use https://sublime.wbond.net/packages/Expand%20Selection%20to%20Whitespace to expand the selection to whitespace if your word contain some random characters, and then press CTDL+D to select next occurrences of the word.
Edit: With the package regex shortcuts indeed you have to create regexes before binding them. But the CTRL+D does work without it.
I don't see a problem with using "Expand selection to whitespace" and than doing the CTRL+D as I wrote in the answer.
I've checked the usage of visual as you wrote in the question and this solution seems much faster to do. You don't have to place cursor in the beggining of the word as It can be whereever in the word and no find/replace is needed, since you'll multiselect all occurrences by holding CTRL+D for a sec and You'll be free to edit it.
You can also use https://sublime.wbond.net/packages/Expand%20Selection%20to%20Quotes to select text inside quote and combine it with CTRL+D if standard CTRL+D doesn't work with some text, or if select to whitespace selects too much text.
I ended up solving this with a simple (if inelegant) plugin:
import sublime_plugin
import sublime
class MultiSelectWithinSelectedCommand(sublime_plugin.TextCommand):
def run(self, edit):
selection = self.view.sel()
new_regions = []
for selected_region in selection:
if selected_region.empty():
selection.add(self.view.word(selected_region))
for selected_region in selection:
if selected_region.a > selected_region.b:
region_begin = selected_region.b
else:
region_begin = selected_region.a
for pos in range(selected_region.size()):
subregion_begin = region_begin + pos
subregion_end = subregion_begin + 1
new_regions.append(sublime.Region(subregion_begin, subregion_end))
selection.clear()
selection.add_all(new_regions)
Once I've stuck this in my plugins directory, I would bind a command in the keymap file like usual:
{ "keys": ["alt+f"], "command": "multi_select_within_selected" }
(with alt+f chosen arbitrarily), and lo, multi-select on all selected characters with a keypress (after which, I can press my replacement character).

Wrapping a code block around code in VIM

Is it possible to wrap a code block around a piece of code in VIM? For example, if I want to wrap a while loop around the following, how can I do it without having to scroll to the bottom of the code to add the closing brace:
if(z > y)
{
switch(x)
{
case 1:
addPoint();
break;
case 2:
addValue();
break;
}
}
This is what the code will look like afterwards:
while (a > 10)
{
if(z > y)
{
switch(x)
{
case 1:
addPoint();
break;
case 2:
addValue();
break;
}
}
}
Vim does not have a built in surrounding system. I suggust you look at Tim Pope's excellent surround plugin. Then assuming you are positioned on the if you can do this:
Vj%SBIwhile (a > 10)
The Vj% selects the block + the conditional.
SB surrounds the selected text with a {,} (read surround with block)
Insert your loop text at the beginning of the newly inserted block.
You don't need surround to do this. You can do it with plain vanilla vim.
Vj%>`]o}<esc>g;g;Owhile (a > 10)<cr>{<esc>
However I prefer to use surround as it is a very handy plugin to have.
For more help see:
:h %
:h g;
:h `]
You can use the vim plugin surround.vim. It lets you wrap lines or fragments in blocks (and change the wrapping pairs).
Check something like Snipmate, it's possible they have an ability of surrounding Visually selected code with a snippit.
http://www.vim.org/scripts/script.php?script_id=2540
snipMate-visual-selection-support There is a special placeholder called {VISUAL}. If you visually select text, then press Vim
switches to insert mode. The next snippet you'll expand will replace
{VISUAL} by the text which was selected previously
You can make a mapping to do this in vanilla Vim e.g.:
:imap <S-F2> <Esc>j>>j>%%o<C-D>}
Use the mapped key after typing the opening brace for the surrounding code. Goes without saying that you should change <S-F2> to a keymap you like.
Breakdown of the key sequence:
Esc: go to Normal mode
j>>: move cursor to next line (in your example the if line) and indent it.
j>%: move cursor to the line with opening brace of if, indent from there to matching brace (the cursor will jump back to the opening brace)
% goes to the closing brace of if
o add a new line after the closing brace, and enter Insert mode.
CTRL+D: unindent (to undo the effect of smartindent)
} add the closing brace for the surround code (in your example, while)
Of course the plugins recommended by others have many more features so you should look at those as well.

Highlighting a code block using viEMU

May I know how do I highlight a code region say for example
public void foo()
{
blah();
blah1();
blah2();
}
where my cursor is at 'b' of first blah(), how can I highlight the whole code region using viEmu or VIM per se?
In Vim, that's va{ (or va}, or vaB as synonyms). The v enters visual mode, and a{ is a text object that selects a Block. If you don't want the curly braces included, use i{ (inner Block) instead. And if you want to operate (e.g. delete) on the block, you can skip visual mode and just use a command that takes a motion, e.g. da{.

Vim: replacing text within function body

I have some very useful plugins to find and replace text through files (see EasyGrep vim script - it's very helpful for programmers). I can even replace text only in the current buffer - by using plugins or :%s .... But what if I just want replace text within the current function body?
Consider the following example:
void f0()
{
int foo = 0;
// ...
}
// 99 other functions that uses foo as local variable.
void f100()
{
int foo = 0; // I want to replace foo with bar only in this function
// 1000 lines of code that uses foo goes below
// ...
}
Of course, I can use :%s ... with c flag for confirmation, but I believe there is a faster way to do this.
Thanks.
You can apply a substitution to the whole file using % or on a selection.
To create a selection :
Go in Visual mode Linewise for example, with Shift+v, select a few line and then type :.
Your prompt will look like :
:'<,'> it means : current selection
Type then s/foo/bar/g and it will replace foo by bar in the current selected line.
The better way to select a function content is to go inside a function with your cursor and type :
vi} it will select everything between { and }.
See :help text-objects for more tips on selection.
You could mark the function with V. Then when you type a command in :, it'll automatically be prefixed by and only be executed in the marked area.
There's probably a command for jumping to beginning of function and end of function, so you could do begin-function, V, end-function, substitute very quickly. Don't know those commands though.
I've always used [[ to jump to the beginning of the function, then use % to jump to the end of the function. I used mt and mb to mark the top and bottom of the function, respectively. Then to search and replace within the marked top and bottom, :'t,'bs/pattern/newpattern/g. This has always worked for me. I'm sure you can create a macro for this.
The visual select (vi}) is much easier and faster. It is aware of the cursor position. So, if the cursor is inside a fucntion sub block, then vi} selects all lines in that block. If you want to select the entire function, one needs to place the cursor outside of the sub blocks then do vi}. This is great for function blocks that fits in the current window. For functions that spans beyond the current window, the selection is lost once scroll up.
I really like the visual select of the vi} because it's so much easier and faster, but I have to resort the old school method on occasion.

Resources