10

There is many times in my day to day work life that I need to operate on a specific function, things like highlighting or searching for a variable, but I have never managed to limit the scope of the edits/search.

Is there a way in vim to selectively say, find all references to $color inside these sets of braces, or this fold etc. If possible, it would be ideal this is relatively generic, so that it could be applied to Editing/Replacing text.

As an Example:

$color = "#fff";
function PickColor () {
  $color = "#bbb";
  $newColors = ["#000", "#fbf", $color];
  foreach ($newColors as $c) {
    if ($c == "#fff") {
       break;
    }
  }
}
$differentColor = $color;

This code is a relatively bad example, however, if I needed to replace all instances of $color how would one do this in the context of the function PickColor. As another example, using # and * You can go to the next instance of that text object, how would you limit the scope for the search to just this function (basically wrapping the search) opposed to the entire file which could span thousands of lines and losing your place, or incorrectly replacing something in another function that you shouldn't have?

15

Here are a few ways to do it.

1  | $color = "#fff";
2  | function PickColor () {
3  |     $color = "#bbb";
4  |     $newColors = ["#000", "#fbf", $color];
5  |     foreach ($newColors as $c) {
6  |         if ($c == "#fff") {
7  |             break;
8  |         }
9  |     }
10 | }
11 | $differentColor = $color;

I've modified your example to include line numbers.

So now you can replace instances of $color, with say $newColor, in the following ways.

Line Number Ranges

:1,11s/\$color/$newColor/g

This makes the substitution operate on lines 1-11 inclusive.

Relative Line Ranges

Place your cursor on line 1, then...

:.,11s/\$color/$newColor/g

This says the range starts with the current line and ends on line 11.

Visual Selection Ranges

Go to line 1 and press Shift+V then G. This visually selects line 1. Then...

:'<,'>:s/\$color/$newColor/g

This limits the substitution to the range covered by your selection. Vim will automatically insert the '<,'> range for you when you press : with an active selection.

  • I love vim, there is always something to learn and discover to make life easier and on a daily basis :) – Kyle Mcgill Feb 3 '15 at 20:43
6

If you're comfortable taking the plugin route, there's NrrwRgn.

You visually select a block, then run the :NR command, which opens a new buffer (in a split) with the selected text. You can make modifications to this buffer, and when you save to it, it gets saved back to the original file as well.

In my opinion, this plugin solves the problem very well, letting you focus on the operations you want to do without re-thinking how to apply them to a specific range.

  • This is one of the plugins I swear by.. it's like having a little scratch buffer that you can commit back to your normal code file. – craigp Feb 4 '15 at 6:57
3

You select the block you are interested in in visual line mode (shift + v) and then you type : and your command which will now apply to the block.

So if you wanted to replace in the selection, you can run :s/string/replacement_string

  • right; e.g., VaB:s/\$color/replaced/g – wchargin Feb 3 '15 at 20:25
  • Just added that, good point :) – Stefan Dorunga Feb 3 '15 at 20:26
0

Use the braces text object '}'and select inside the braces with 'i}'

on the line with the opening curly brace of the function:

$<C-V>i}:s/\$color/$newColor/g

first go to the end of the line (which will be on or inside the opening brace) then to go into visual select, then select using the braces text object. 'i}' is inside braces 'a}' is around braces.

For languages that lack braces, Vim Text Object: The Definitive Guide suggests some plugins:

  • For languages like Python and CoffeeScript, Indent Object provides text objects based on indentation level: ai includes the current indentation level and the line above; ii includes the current indentation level excluding the line above.
  • Ruby Block adds support for text objects ar and ir, based on the presence of the end keyword.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.