tags:

views:

101

answers:

4

I have to work on some relatively huge code files in vim.

How do I restrict some operations like find-next normal-n and others to a certain function / block?

How would I visually know if I'm within that block or outside it?

Looking and line numbers seems awkward, specially that the line numbers I need to work with are generally 5 digits long!

A: 

Vim uses Shift-v to select by lines. Having selected a series of lines, many commands will then be restricted to the selection.

I don't think the search commands (/, n, etc.) are restricted that way though.

bignose
Don't add [belongs-on-XXX] tags. http://meta.stackoverflow.com/questions/10216/can-we-disallow-the-use-of-belongs-on-xxxxxxx-and-not-programming-related-tag
Roger Pate
But then I have to be in visual select mode all the time. Not convenient.
Ayman
A: 

For commands like search and replace, you can easily limit yourself to a couple of lines:

:.,+3s/foo/bar/cg

replaces every occurrence of "foo" in the current line and the following 3 lines with "bar". I don't think you can do that for search, though.

Tomislav Nakic-Alfirevic
problem is, my "block" to manipulate is over 1000 lines, from a total of over 20k. And I may add / delete lines, so that would not work.
Ayman
Tomislav Nakic-Alfirevic
+1  A: 

Vimtips has exactly what you were looking for:

Search in current function

See also :help pattern-atoms

TheOsp
+2  A: 

You can set marks at the beginning and end of your block using m (e.g. ma, mb) and then refer to them in the range of a ex command as :'a,'b.

Like bignose said you can use a visual block to create an implicit region for a command, which can be passed to an ex command using :'<,'>

You can also use regexes to delimit a block (e.g. for all the lines between start and end use :/start/,/end/

For example, to make a substitution in a range of lines:

:'<,'>s/foo/bar/g
:'a,'bs/baz/quux/g
:/harpo/,/chico/s/zeppo/groucho/g

The last visually selected range is remembered so you can reuse it without reselecting it.

For more on ranges, see :help range

You can further restrict yourself within a range by using g//. For example, if you wanted to replace foo with bar only on lines containing baz in the selected range:

:'<,'>g/baz/s/foo/bar/g

When you define a new ex command, you can pass the range given to the ex-command using as <line1>,<line2>. See :help user-commands for more on defining ex-commands.

Within a vimscript function, you can access an implicitly passed range using a:firstline and a:lastline. You can detect your current linenumber using line('.'), and detect whether you're inside the block using normal boolean logic (a:firstline <= line('.') && line('.') <= a:lastline). See :help functions for more on vimscript functions.


Another approach, is to use vim's inner i and single a selectors. For example, to delete the entirety of a double quoted string, use da" in normal mode. To leave the quotes, use di". See :help object-select for more.

rampion