Changing variable names in Vim












85















I am trying to read a lot of C/Perl code through Vim which contain many single letter variable names.



It would be nice to have some command which could help me change the name of a variable to something more meaningful while I'm in the process of reading the code so that I could read the rest of it faster.



Is there some command in Vim which could let me quickly do this?



I don't think regexes would work because:




  1. the same single letter name might have different purposes in different scoping blocks


  2. the same combination of letters could be part of another larger var name, or in a string or comment... would not want to modify those



Any known solutions?










share|improve this question





























    85















    I am trying to read a lot of C/Perl code through Vim which contain many single letter variable names.



    It would be nice to have some command which could help me change the name of a variable to something more meaningful while I'm in the process of reading the code so that I could read the rest of it faster.



    Is there some command in Vim which could let me quickly do this?



    I don't think regexes would work because:




    1. the same single letter name might have different purposes in different scoping blocks


    2. the same combination of letters could be part of another larger var name, or in a string or comment... would not want to modify those



    Any known solutions?










    share|improve this question



























      85












      85








      85


      61






      I am trying to read a lot of C/Perl code through Vim which contain many single letter variable names.



      It would be nice to have some command which could help me change the name of a variable to something more meaningful while I'm in the process of reading the code so that I could read the rest of it faster.



      Is there some command in Vim which could let me quickly do this?



      I don't think regexes would work because:




      1. the same single letter name might have different purposes in different scoping blocks


      2. the same combination of letters could be part of another larger var name, or in a string or comment... would not want to modify those



      Any known solutions?










      share|improve this question
















      I am trying to read a lot of C/Perl code through Vim which contain many single letter variable names.



      It would be nice to have some command which could help me change the name of a variable to something more meaningful while I'm in the process of reading the code so that I could read the rest of it faster.



      Is there some command in Vim which could let me quickly do this?



      I don't think regexes would work because:




      1. the same single letter name might have different purposes in different scoping blocks


      2. the same combination of letters could be part of another larger var name, or in a string or comment... would not want to modify those



      Any known solutions?







      vim variables refactoring






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jul 19 '18 at 19:09









      Community

      11




      11










      asked Feb 28 '09 at 7:29









      Aditya MukherjiAditya Mukherji

      7,39943244




      7,39943244
























          7 Answers
          7






          active

          oldest

          votes


















          175














          The following is how to rename a variable which is defined in the current scope {}.



          Move your cursor to the variable usage. Press gd. Which means - move cursor to the definition.
          Now Press [{ - this will bring you to the scope begin.
          Press V - will turn on Visual Line selection.
          Press % - will jump to the opposite } thus will select the whole scope.
          Press :s/ - start of the substitute command.
          <C-R>/ - will insert pattern that match variable name (that name you were on before pressing gd).
          /newname/gc<CR> - will initiate search and replace with confirmation on every match.



          Now you have to record a macros or even better - map a key.



          Here are the final mappings:



          " For local replace
          nnoremap gr gd[{V%::s/<C-R>///gc<left><left><left>

          " For global replace
          nnoremap gR gD:%s/<C-R>///gc<left><left><left>


          Put this to your .vimrc or just execute.
          After this pressing gr on the local variable will bring you to :s command where you simply should enter new_variable_name and press Enter.






          share|improve this answer





















          • 32





            +1 for learning more than 5 new Vim tricks I should have known before. Thanks

            – Kenny Meyer
            Dec 14 '10 at 14:15






          • 6





            Note: gd doesn't work to locate the variable in the immediate scope of definition in Javascript mode in macvim. It takes me to the first use of the variable name in some function in the file :( If you're within some scope and want to select that scope, "va{" - "visual select around {" - is the way to go I think.

            – Srikumar
            Nov 29 '11 at 3:07








          • 3





            A slightly improved version: gist.github.com/048616a2e3f5d1b5a9ad prompts user, shows old name, restores cursor position after replace

            – Andy Ray
            Dec 19 '11 at 5:51






          • 7





            +1 very good vimgineering (I think I just coined a new term). Note: I actually needed to press colon (:) twice. The first time I pressed it, I saw :'<,'>. If I just typed s/ from there it didn't work; I had to type another colon before the s/.

            – Kelvin
            Mar 20 '12 at 21:14








          • 4





            Note you don't need <C-R> in the substitute command, simply omitting the search will cause vim to use the last searched pattern, which in this case was created from the gd command. So simply doing :s//<newname>/gc will suffice.

            – shangxiao
            Jan 4 '17 at 8:12



















          9














          AFAIK, there is no actual refactoring support in VIM. When doing a rename with the intent of a refactor I usually take the following precautions:




          1. Limit the scope of the change my using marks.

          2. When entering the regex, bracket the name with < and >. This will make it match an entire word which reduces the types of incorrect renames that will occur.

          3. Don't do a multiline replace to reduce chances of a bad replace

          4. Look through the code diff carefully if it's anything other than a small change.


          My end change looks something like this



          :'a,'bs/<foo>/bar


          I would love to be wrong about there not being a refactoring tool for VIM but I haven't seen it.






          share|improve this answer


























          • In Perl you can also add the type to the search pattern. i.e. $ for scalars, @ for arrays, % for hashes

            – Nathan Fellman
            Feb 28 '09 at 12:39











          • @Nathan: unfortunately, it's a bit more difficult in Perl (5.X), as the sigil of arrays and hashes changes with the usage: %hash -> whole hash, $hash{key} -> single value, @hash{qw/a b/} hash slice.

            – user55400
            Mar 2 '09 at 13:39



















          8














          Put this in your .vimrc



          " Function to rename the variable under the cursor
          function! Rnvar()
          let word_to_replace = expand("<cword>")
          let replacement = input("new name: ")
          execute '%s/(W)' . word_to_replace . '(W)/1' . replacement . '2/gc'
          endfunction


          Call it with :call Rnvar()



          expand("<cword>") gets the word under the cursor. The search string uses % for file-scope, and the (W) patterns look for non-word characters at the boundary of the word to replace, and save them in variables 1 and 2 so as to be re-inserted in the replacement pattern.






          share|improve this answer































            7














            I know it's an old question, and @mykola-golubyev's way obviously IS the best answer for the particular case in the OP question (which, I assume is going through obfuscated code where you're likely to have multiple blocks with same var names); but with the question name like that many people coming here from google searches probably look for a less situation-specific ways to rename variables in VIM -- and those can be more concise



            I'm surprized no one suggested this way:




            * :s// NEWNAME /gc




            The * is the same as gn - it searches for the next occurence of the word under cursor AND it becomes the last searched pattern, so when you omit the search pattern in the substitute command, VIM assumes this is the pattern to search for.



            For small amounts of var copies, an even quicker one:




            * cw NEWNAME <esc> then repeat n. for other occurrences




            Search for occurrence, cw is command for change word, n goes to next occurrence for last search and . repeats the last command (which is change word to NEWNAME)



            (Credits for me knowing all this go to @doomedbunnies on Reddit)



            Another cool trick is this: (credits to @nobe4)




            * cgn NEWNAME <esc> then repeat . for other occurrences




            cgn is "change whatever is the result of (find next occurrence)". Now that this is the last command, you don't need the n to go to the next occurrence, so fewer strokes again, and, more importantly, no need to alternate n and .. But, obviously, this one has the drawback of not having a way to skip an occurrence.



            Here are some benefits:




            • no mapping, no .vimrc(or init.vim), so you can use it in any VIM copy you come across (e.g. a quick task on some VPS or your friend's machine where configuring VIM your way would defeat the purpose of 'quick')

            • using * or gn for word selection is very quick -- just one keystroke (well, let's say 1.5)

            • using * or gn makes sure you don't get any matches inside other words, just as :%s/<C-R>//gc does. Beats typing the :%s/<OLDNAME>/NEWNAME/gc by hand: I personally tend to forget to use the < things to limit matches to whole words only.

            • Not using scope will only result in a few extra strokes of n to skip unwanted matches -- probably even fewer than the extra strokes needed to limit the scope. Under normal curcumstances, your variables are most likely somewhat localized to a certain code block anyway.






            share|improve this answer

































              2














              You could use the 'c' modifier in the global search and replace that would ask you for confirmation for each replace. It would take longer but it might work for a non-humongous code file:



              %s/$var/$foo/gc


              The c stands for confirm.






              share|improve this answer


























              • The i stands for ignore-case. You want c, confirm every change.

                – Michael Kristofik
                Feb 28 '09 at 13:49











              • Not sure that you need to escape the $ of foo...

                – Luc M
                Feb 28 '09 at 14:12











              • oops.. sorry about that.. Fixed the answer

                – Adnan
                Feb 28 '09 at 23:19











              • Answer still not fixed completely ;)

                – user55400
                Mar 2 '09 at 13:40











              • did you mean the escaped $? That's something that's kind of a personal preference of mine. $ works without escape and also with and since in the regex world and in vi $ has special meaning, I like to escape it just for clarity.

                – Adnan
                Mar 2 '09 at 23:33



















              0














              In c, you may be able to make some progress using cscope. It makes an attempt at understanding syntax, so would have a chance of knowing when the letter was a variable.






              share|improve this answer































                0














                If this is across multiple files, you may consider taking a look at sed. Use find to grab your files and xargs plus sed for a replace. Say you want to replace a with a_better_name in all files matching *.c, you could do



                find . -name "*.c" | xargs sed -i -e 's/a/a_better_name/g'



                Bear in mind that this will replace ALL occurrences of a, so you may want a more robust regex.






                share|improve this answer























                  Your Answer






                  StackExchange.ifUsing("editor", function () {
                  StackExchange.using("externalEditor", function () {
                  StackExchange.using("snippets", function () {
                  StackExchange.snippets.init();
                  });
                  });
                  }, "code-snippets");

                  StackExchange.ready(function() {
                  var channelOptions = {
                  tags: "".split(" "),
                  id: "1"
                  };
                  initTagRenderer("".split(" "), "".split(" "), channelOptions);

                  StackExchange.using("externalEditor", function() {
                  // Have to fire editor after snippets, if snippets enabled
                  if (StackExchange.settings.snippets.snippetsEnabled) {
                  StackExchange.using("snippets", function() {
                  createEditor();
                  });
                  }
                  else {
                  createEditor();
                  }
                  });

                  function createEditor() {
                  StackExchange.prepareEditor({
                  heartbeatType: 'answer',
                  autoActivateHeartbeat: false,
                  convertImagesToLinks: true,
                  noModals: true,
                  showLowRepImageUploadWarning: true,
                  reputationToPostImages: 10,
                  bindNavPrevention: true,
                  postfix: "",
                  imageUploader: {
                  brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                  contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                  allowUrls: true
                  },
                  onDemand: true,
                  discardSelector: ".discard-answer"
                  ,immediatelyShowMarkdownHelp:true
                  });


                  }
                  });














                  draft saved

                  draft discarded


















                  StackExchange.ready(
                  function () {
                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f597687%2fchanging-variable-names-in-vim%23new-answer', 'question_page');
                  }
                  );

                  Post as a guest















                  Required, but never shown

























                  7 Answers
                  7






                  active

                  oldest

                  votes








                  7 Answers
                  7






                  active

                  oldest

                  votes









                  active

                  oldest

                  votes






                  active

                  oldest

                  votes









                  175














                  The following is how to rename a variable which is defined in the current scope {}.



                  Move your cursor to the variable usage. Press gd. Which means - move cursor to the definition.
                  Now Press [{ - this will bring you to the scope begin.
                  Press V - will turn on Visual Line selection.
                  Press % - will jump to the opposite } thus will select the whole scope.
                  Press :s/ - start of the substitute command.
                  <C-R>/ - will insert pattern that match variable name (that name you were on before pressing gd).
                  /newname/gc<CR> - will initiate search and replace with confirmation on every match.



                  Now you have to record a macros or even better - map a key.



                  Here are the final mappings:



                  " For local replace
                  nnoremap gr gd[{V%::s/<C-R>///gc<left><left><left>

                  " For global replace
                  nnoremap gR gD:%s/<C-R>///gc<left><left><left>


                  Put this to your .vimrc or just execute.
                  After this pressing gr on the local variable will bring you to :s command where you simply should enter new_variable_name and press Enter.






                  share|improve this answer





















                  • 32





                    +1 for learning more than 5 new Vim tricks I should have known before. Thanks

                    – Kenny Meyer
                    Dec 14 '10 at 14:15






                  • 6





                    Note: gd doesn't work to locate the variable in the immediate scope of definition in Javascript mode in macvim. It takes me to the first use of the variable name in some function in the file :( If you're within some scope and want to select that scope, "va{" - "visual select around {" - is the way to go I think.

                    – Srikumar
                    Nov 29 '11 at 3:07








                  • 3





                    A slightly improved version: gist.github.com/048616a2e3f5d1b5a9ad prompts user, shows old name, restores cursor position after replace

                    – Andy Ray
                    Dec 19 '11 at 5:51






                  • 7





                    +1 very good vimgineering (I think I just coined a new term). Note: I actually needed to press colon (:) twice. The first time I pressed it, I saw :'<,'>. If I just typed s/ from there it didn't work; I had to type another colon before the s/.

                    – Kelvin
                    Mar 20 '12 at 21:14








                  • 4





                    Note you don't need <C-R> in the substitute command, simply omitting the search will cause vim to use the last searched pattern, which in this case was created from the gd command. So simply doing :s//<newname>/gc will suffice.

                    – shangxiao
                    Jan 4 '17 at 8:12
















                  175














                  The following is how to rename a variable which is defined in the current scope {}.



                  Move your cursor to the variable usage. Press gd. Which means - move cursor to the definition.
                  Now Press [{ - this will bring you to the scope begin.
                  Press V - will turn on Visual Line selection.
                  Press % - will jump to the opposite } thus will select the whole scope.
                  Press :s/ - start of the substitute command.
                  <C-R>/ - will insert pattern that match variable name (that name you were on before pressing gd).
                  /newname/gc<CR> - will initiate search and replace with confirmation on every match.



                  Now you have to record a macros or even better - map a key.



                  Here are the final mappings:



                  " For local replace
                  nnoremap gr gd[{V%::s/<C-R>///gc<left><left><left>

                  " For global replace
                  nnoremap gR gD:%s/<C-R>///gc<left><left><left>


                  Put this to your .vimrc or just execute.
                  After this pressing gr on the local variable will bring you to :s command where you simply should enter new_variable_name and press Enter.






                  share|improve this answer





















                  • 32





                    +1 for learning more than 5 new Vim tricks I should have known before. Thanks

                    – Kenny Meyer
                    Dec 14 '10 at 14:15






                  • 6





                    Note: gd doesn't work to locate the variable in the immediate scope of definition in Javascript mode in macvim. It takes me to the first use of the variable name in some function in the file :( If you're within some scope and want to select that scope, "va{" - "visual select around {" - is the way to go I think.

                    – Srikumar
                    Nov 29 '11 at 3:07








                  • 3





                    A slightly improved version: gist.github.com/048616a2e3f5d1b5a9ad prompts user, shows old name, restores cursor position after replace

                    – Andy Ray
                    Dec 19 '11 at 5:51






                  • 7





                    +1 very good vimgineering (I think I just coined a new term). Note: I actually needed to press colon (:) twice. The first time I pressed it, I saw :'<,'>. If I just typed s/ from there it didn't work; I had to type another colon before the s/.

                    – Kelvin
                    Mar 20 '12 at 21:14








                  • 4





                    Note you don't need <C-R> in the substitute command, simply omitting the search will cause vim to use the last searched pattern, which in this case was created from the gd command. So simply doing :s//<newname>/gc will suffice.

                    – shangxiao
                    Jan 4 '17 at 8:12














                  175












                  175








                  175







                  The following is how to rename a variable which is defined in the current scope {}.



                  Move your cursor to the variable usage. Press gd. Which means - move cursor to the definition.
                  Now Press [{ - this will bring you to the scope begin.
                  Press V - will turn on Visual Line selection.
                  Press % - will jump to the opposite } thus will select the whole scope.
                  Press :s/ - start of the substitute command.
                  <C-R>/ - will insert pattern that match variable name (that name you were on before pressing gd).
                  /newname/gc<CR> - will initiate search and replace with confirmation on every match.



                  Now you have to record a macros or even better - map a key.



                  Here are the final mappings:



                  " For local replace
                  nnoremap gr gd[{V%::s/<C-R>///gc<left><left><left>

                  " For global replace
                  nnoremap gR gD:%s/<C-R>///gc<left><left><left>


                  Put this to your .vimrc or just execute.
                  After this pressing gr on the local variable will bring you to :s command where you simply should enter new_variable_name and press Enter.






                  share|improve this answer















                  The following is how to rename a variable which is defined in the current scope {}.



                  Move your cursor to the variable usage. Press gd. Which means - move cursor to the definition.
                  Now Press [{ - this will bring you to the scope begin.
                  Press V - will turn on Visual Line selection.
                  Press % - will jump to the opposite } thus will select the whole scope.
                  Press :s/ - start of the substitute command.
                  <C-R>/ - will insert pattern that match variable name (that name you were on before pressing gd).
                  /newname/gc<CR> - will initiate search and replace with confirmation on every match.



                  Now you have to record a macros or even better - map a key.



                  Here are the final mappings:



                  " For local replace
                  nnoremap gr gd[{V%::s/<C-R>///gc<left><left><left>

                  " For global replace
                  nnoremap gR gD:%s/<C-R>///gc<left><left><left>


                  Put this to your .vimrc or just execute.
                  After this pressing gr on the local variable will bring you to :s command where you simply should enter new_variable_name and press Enter.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Apr 29 '14 at 15:47









                  kevlar1818

                  2,02121838




                  2,02121838










                  answered Feb 28 '09 at 12:00









                  Mykola GolubyevMykola Golubyev

                  43.4k127194




                  43.4k127194








                  • 32





                    +1 for learning more than 5 new Vim tricks I should have known before. Thanks

                    – Kenny Meyer
                    Dec 14 '10 at 14:15






                  • 6





                    Note: gd doesn't work to locate the variable in the immediate scope of definition in Javascript mode in macvim. It takes me to the first use of the variable name in some function in the file :( If you're within some scope and want to select that scope, "va{" - "visual select around {" - is the way to go I think.

                    – Srikumar
                    Nov 29 '11 at 3:07








                  • 3





                    A slightly improved version: gist.github.com/048616a2e3f5d1b5a9ad prompts user, shows old name, restores cursor position after replace

                    – Andy Ray
                    Dec 19 '11 at 5:51






                  • 7





                    +1 very good vimgineering (I think I just coined a new term). Note: I actually needed to press colon (:) twice. The first time I pressed it, I saw :'<,'>. If I just typed s/ from there it didn't work; I had to type another colon before the s/.

                    – Kelvin
                    Mar 20 '12 at 21:14








                  • 4





                    Note you don't need <C-R> in the substitute command, simply omitting the search will cause vim to use the last searched pattern, which in this case was created from the gd command. So simply doing :s//<newname>/gc will suffice.

                    – shangxiao
                    Jan 4 '17 at 8:12














                  • 32





                    +1 for learning more than 5 new Vim tricks I should have known before. Thanks

                    – Kenny Meyer
                    Dec 14 '10 at 14:15






                  • 6





                    Note: gd doesn't work to locate the variable in the immediate scope of definition in Javascript mode in macvim. It takes me to the first use of the variable name in some function in the file :( If you're within some scope and want to select that scope, "va{" - "visual select around {" - is the way to go I think.

                    – Srikumar
                    Nov 29 '11 at 3:07








                  • 3





                    A slightly improved version: gist.github.com/048616a2e3f5d1b5a9ad prompts user, shows old name, restores cursor position after replace

                    – Andy Ray
                    Dec 19 '11 at 5:51






                  • 7





                    +1 very good vimgineering (I think I just coined a new term). Note: I actually needed to press colon (:) twice. The first time I pressed it, I saw :'<,'>. If I just typed s/ from there it didn't work; I had to type another colon before the s/.

                    – Kelvin
                    Mar 20 '12 at 21:14








                  • 4





                    Note you don't need <C-R> in the substitute command, simply omitting the search will cause vim to use the last searched pattern, which in this case was created from the gd command. So simply doing :s//<newname>/gc will suffice.

                    – shangxiao
                    Jan 4 '17 at 8:12








                  32




                  32





                  +1 for learning more than 5 new Vim tricks I should have known before. Thanks

                  – Kenny Meyer
                  Dec 14 '10 at 14:15





                  +1 for learning more than 5 new Vim tricks I should have known before. Thanks

                  – Kenny Meyer
                  Dec 14 '10 at 14:15




                  6




                  6





                  Note: gd doesn't work to locate the variable in the immediate scope of definition in Javascript mode in macvim. It takes me to the first use of the variable name in some function in the file :( If you're within some scope and want to select that scope, "va{" - "visual select around {" - is the way to go I think.

                  – Srikumar
                  Nov 29 '11 at 3:07







                  Note: gd doesn't work to locate the variable in the immediate scope of definition in Javascript mode in macvim. It takes me to the first use of the variable name in some function in the file :( If you're within some scope and want to select that scope, "va{" - "visual select around {" - is the way to go I think.

                  – Srikumar
                  Nov 29 '11 at 3:07






                  3




                  3





                  A slightly improved version: gist.github.com/048616a2e3f5d1b5a9ad prompts user, shows old name, restores cursor position after replace

                  – Andy Ray
                  Dec 19 '11 at 5:51





                  A slightly improved version: gist.github.com/048616a2e3f5d1b5a9ad prompts user, shows old name, restores cursor position after replace

                  – Andy Ray
                  Dec 19 '11 at 5:51




                  7




                  7





                  +1 very good vimgineering (I think I just coined a new term). Note: I actually needed to press colon (:) twice. The first time I pressed it, I saw :'<,'>. If I just typed s/ from there it didn't work; I had to type another colon before the s/.

                  – Kelvin
                  Mar 20 '12 at 21:14







                  +1 very good vimgineering (I think I just coined a new term). Note: I actually needed to press colon (:) twice. The first time I pressed it, I saw :'<,'>. If I just typed s/ from there it didn't work; I had to type another colon before the s/.

                  – Kelvin
                  Mar 20 '12 at 21:14






                  4




                  4





                  Note you don't need <C-R> in the substitute command, simply omitting the search will cause vim to use the last searched pattern, which in this case was created from the gd command. So simply doing :s//<newname>/gc will suffice.

                  – shangxiao
                  Jan 4 '17 at 8:12





                  Note you don't need <C-R> in the substitute command, simply omitting the search will cause vim to use the last searched pattern, which in this case was created from the gd command. So simply doing :s//<newname>/gc will suffice.

                  – shangxiao
                  Jan 4 '17 at 8:12













                  9














                  AFAIK, there is no actual refactoring support in VIM. When doing a rename with the intent of a refactor I usually take the following precautions:




                  1. Limit the scope of the change my using marks.

                  2. When entering the regex, bracket the name with < and >. This will make it match an entire word which reduces the types of incorrect renames that will occur.

                  3. Don't do a multiline replace to reduce chances of a bad replace

                  4. Look through the code diff carefully if it's anything other than a small change.


                  My end change looks something like this



                  :'a,'bs/<foo>/bar


                  I would love to be wrong about there not being a refactoring tool for VIM but I haven't seen it.






                  share|improve this answer


























                  • In Perl you can also add the type to the search pattern. i.e. $ for scalars, @ for arrays, % for hashes

                    – Nathan Fellman
                    Feb 28 '09 at 12:39











                  • @Nathan: unfortunately, it's a bit more difficult in Perl (5.X), as the sigil of arrays and hashes changes with the usage: %hash -> whole hash, $hash{key} -> single value, @hash{qw/a b/} hash slice.

                    – user55400
                    Mar 2 '09 at 13:39
















                  9














                  AFAIK, there is no actual refactoring support in VIM. When doing a rename with the intent of a refactor I usually take the following precautions:




                  1. Limit the scope of the change my using marks.

                  2. When entering the regex, bracket the name with < and >. This will make it match an entire word which reduces the types of incorrect renames that will occur.

                  3. Don't do a multiline replace to reduce chances of a bad replace

                  4. Look through the code diff carefully if it's anything other than a small change.


                  My end change looks something like this



                  :'a,'bs/<foo>/bar


                  I would love to be wrong about there not being a refactoring tool for VIM but I haven't seen it.






                  share|improve this answer


























                  • In Perl you can also add the type to the search pattern. i.e. $ for scalars, @ for arrays, % for hashes

                    – Nathan Fellman
                    Feb 28 '09 at 12:39











                  • @Nathan: unfortunately, it's a bit more difficult in Perl (5.X), as the sigil of arrays and hashes changes with the usage: %hash -> whole hash, $hash{key} -> single value, @hash{qw/a b/} hash slice.

                    – user55400
                    Mar 2 '09 at 13:39














                  9












                  9








                  9







                  AFAIK, there is no actual refactoring support in VIM. When doing a rename with the intent of a refactor I usually take the following precautions:




                  1. Limit the scope of the change my using marks.

                  2. When entering the regex, bracket the name with < and >. This will make it match an entire word which reduces the types of incorrect renames that will occur.

                  3. Don't do a multiline replace to reduce chances of a bad replace

                  4. Look through the code diff carefully if it's anything other than a small change.


                  My end change looks something like this



                  :'a,'bs/<foo>/bar


                  I would love to be wrong about there not being a refactoring tool for VIM but I haven't seen it.






                  share|improve this answer















                  AFAIK, there is no actual refactoring support in VIM. When doing a rename with the intent of a refactor I usually take the following precautions:




                  1. Limit the scope of the change my using marks.

                  2. When entering the regex, bracket the name with < and >. This will make it match an entire word which reduces the types of incorrect renames that will occur.

                  3. Don't do a multiline replace to reduce chances of a bad replace

                  4. Look through the code diff carefully if it's anything other than a small change.


                  My end change looks something like this



                  :'a,'bs/<foo>/bar


                  I would love to be wrong about there not being a refactoring tool for VIM but I haven't seen it.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jul 20 '18 at 1:12









                  Community

                  11




                  11










                  answered Feb 28 '09 at 7:35









                  JaredParJaredPar

                  573k11910611343




                  573k11910611343













                  • In Perl you can also add the type to the search pattern. i.e. $ for scalars, @ for arrays, % for hashes

                    – Nathan Fellman
                    Feb 28 '09 at 12:39











                  • @Nathan: unfortunately, it's a bit more difficult in Perl (5.X), as the sigil of arrays and hashes changes with the usage: %hash -> whole hash, $hash{key} -> single value, @hash{qw/a b/} hash slice.

                    – user55400
                    Mar 2 '09 at 13:39



















                  • In Perl you can also add the type to the search pattern. i.e. $ for scalars, @ for arrays, % for hashes

                    – Nathan Fellman
                    Feb 28 '09 at 12:39











                  • @Nathan: unfortunately, it's a bit more difficult in Perl (5.X), as the sigil of arrays and hashes changes with the usage: %hash -> whole hash, $hash{key} -> single value, @hash{qw/a b/} hash slice.

                    – user55400
                    Mar 2 '09 at 13:39

















                  In Perl you can also add the type to the search pattern. i.e. $ for scalars, @ for arrays, % for hashes

                  – Nathan Fellman
                  Feb 28 '09 at 12:39





                  In Perl you can also add the type to the search pattern. i.e. $ for scalars, @ for arrays, % for hashes

                  – Nathan Fellman
                  Feb 28 '09 at 12:39













                  @Nathan: unfortunately, it's a bit more difficult in Perl (5.X), as the sigil of arrays and hashes changes with the usage: %hash -> whole hash, $hash{key} -> single value, @hash{qw/a b/} hash slice.

                  – user55400
                  Mar 2 '09 at 13:39





                  @Nathan: unfortunately, it's a bit more difficult in Perl (5.X), as the sigil of arrays and hashes changes with the usage: %hash -> whole hash, $hash{key} -> single value, @hash{qw/a b/} hash slice.

                  – user55400
                  Mar 2 '09 at 13:39











                  8














                  Put this in your .vimrc



                  " Function to rename the variable under the cursor
                  function! Rnvar()
                  let word_to_replace = expand("<cword>")
                  let replacement = input("new name: ")
                  execute '%s/(W)' . word_to_replace . '(W)/1' . replacement . '2/gc'
                  endfunction


                  Call it with :call Rnvar()



                  expand("<cword>") gets the word under the cursor. The search string uses % for file-scope, and the (W) patterns look for non-word characters at the boundary of the word to replace, and save them in variables 1 and 2 so as to be re-inserted in the replacement pattern.






                  share|improve this answer




























                    8














                    Put this in your .vimrc



                    " Function to rename the variable under the cursor
                    function! Rnvar()
                    let word_to_replace = expand("<cword>")
                    let replacement = input("new name: ")
                    execute '%s/(W)' . word_to_replace . '(W)/1' . replacement . '2/gc'
                    endfunction


                    Call it with :call Rnvar()



                    expand("<cword>") gets the word under the cursor. The search string uses % for file-scope, and the (W) patterns look for non-word characters at the boundary of the word to replace, and save them in variables 1 and 2 so as to be re-inserted in the replacement pattern.






                    share|improve this answer


























                      8












                      8








                      8







                      Put this in your .vimrc



                      " Function to rename the variable under the cursor
                      function! Rnvar()
                      let word_to_replace = expand("<cword>")
                      let replacement = input("new name: ")
                      execute '%s/(W)' . word_to_replace . '(W)/1' . replacement . '2/gc'
                      endfunction


                      Call it with :call Rnvar()



                      expand("<cword>") gets the word under the cursor. The search string uses % for file-scope, and the (W) patterns look for non-word characters at the boundary of the word to replace, and save them in variables 1 and 2 so as to be re-inserted in the replacement pattern.






                      share|improve this answer













                      Put this in your .vimrc



                      " Function to rename the variable under the cursor
                      function! Rnvar()
                      let word_to_replace = expand("<cword>")
                      let replacement = input("new name: ")
                      execute '%s/(W)' . word_to_replace . '(W)/1' . replacement . '2/gc'
                      endfunction


                      Call it with :call Rnvar()



                      expand("<cword>") gets the word under the cursor. The search string uses % for file-scope, and the (W) patterns look for non-word characters at the boundary of the word to replace, and save them in variables 1 and 2 so as to be re-inserted in the replacement pattern.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Nov 14 '13 at 0:35









                      MikeMike

                      8113




                      8113























                          7














                          I know it's an old question, and @mykola-golubyev's way obviously IS the best answer for the particular case in the OP question (which, I assume is going through obfuscated code where you're likely to have multiple blocks with same var names); but with the question name like that many people coming here from google searches probably look for a less situation-specific ways to rename variables in VIM -- and those can be more concise



                          I'm surprized no one suggested this way:




                          * :s// NEWNAME /gc




                          The * is the same as gn - it searches for the next occurence of the word under cursor AND it becomes the last searched pattern, so when you omit the search pattern in the substitute command, VIM assumes this is the pattern to search for.



                          For small amounts of var copies, an even quicker one:




                          * cw NEWNAME <esc> then repeat n. for other occurrences




                          Search for occurrence, cw is command for change word, n goes to next occurrence for last search and . repeats the last command (which is change word to NEWNAME)



                          (Credits for me knowing all this go to @doomedbunnies on Reddit)



                          Another cool trick is this: (credits to @nobe4)




                          * cgn NEWNAME <esc> then repeat . for other occurrences




                          cgn is "change whatever is the result of (find next occurrence)". Now that this is the last command, you don't need the n to go to the next occurrence, so fewer strokes again, and, more importantly, no need to alternate n and .. But, obviously, this one has the drawback of not having a way to skip an occurrence.



                          Here are some benefits:




                          • no mapping, no .vimrc(or init.vim), so you can use it in any VIM copy you come across (e.g. a quick task on some VPS or your friend's machine where configuring VIM your way would defeat the purpose of 'quick')

                          • using * or gn for word selection is very quick -- just one keystroke (well, let's say 1.5)

                          • using * or gn makes sure you don't get any matches inside other words, just as :%s/<C-R>//gc does. Beats typing the :%s/<OLDNAME>/NEWNAME/gc by hand: I personally tend to forget to use the < things to limit matches to whole words only.

                          • Not using scope will only result in a few extra strokes of n to skip unwanted matches -- probably even fewer than the extra strokes needed to limit the scope. Under normal curcumstances, your variables are most likely somewhat localized to a certain code block anyway.






                          share|improve this answer






























                            7














                            I know it's an old question, and @mykola-golubyev's way obviously IS the best answer for the particular case in the OP question (which, I assume is going through obfuscated code where you're likely to have multiple blocks with same var names); but with the question name like that many people coming here from google searches probably look for a less situation-specific ways to rename variables in VIM -- and those can be more concise



                            I'm surprized no one suggested this way:




                            * :s// NEWNAME /gc




                            The * is the same as gn - it searches for the next occurence of the word under cursor AND it becomes the last searched pattern, so when you omit the search pattern in the substitute command, VIM assumes this is the pattern to search for.



                            For small amounts of var copies, an even quicker one:




                            * cw NEWNAME <esc> then repeat n. for other occurrences




                            Search for occurrence, cw is command for change word, n goes to next occurrence for last search and . repeats the last command (which is change word to NEWNAME)



                            (Credits for me knowing all this go to @doomedbunnies on Reddit)



                            Another cool trick is this: (credits to @nobe4)




                            * cgn NEWNAME <esc> then repeat . for other occurrences




                            cgn is "change whatever is the result of (find next occurrence)". Now that this is the last command, you don't need the n to go to the next occurrence, so fewer strokes again, and, more importantly, no need to alternate n and .. But, obviously, this one has the drawback of not having a way to skip an occurrence.



                            Here are some benefits:




                            • no mapping, no .vimrc(or init.vim), so you can use it in any VIM copy you come across (e.g. a quick task on some VPS or your friend's machine where configuring VIM your way would defeat the purpose of 'quick')

                            • using * or gn for word selection is very quick -- just one keystroke (well, let's say 1.5)

                            • using * or gn makes sure you don't get any matches inside other words, just as :%s/<C-R>//gc does. Beats typing the :%s/<OLDNAME>/NEWNAME/gc by hand: I personally tend to forget to use the < things to limit matches to whole words only.

                            • Not using scope will only result in a few extra strokes of n to skip unwanted matches -- probably even fewer than the extra strokes needed to limit the scope. Under normal curcumstances, your variables are most likely somewhat localized to a certain code block anyway.






                            share|improve this answer




























                              7












                              7








                              7







                              I know it's an old question, and @mykola-golubyev's way obviously IS the best answer for the particular case in the OP question (which, I assume is going through obfuscated code where you're likely to have multiple blocks with same var names); but with the question name like that many people coming here from google searches probably look for a less situation-specific ways to rename variables in VIM -- and those can be more concise



                              I'm surprized no one suggested this way:




                              * :s// NEWNAME /gc




                              The * is the same as gn - it searches for the next occurence of the word under cursor AND it becomes the last searched pattern, so when you omit the search pattern in the substitute command, VIM assumes this is the pattern to search for.



                              For small amounts of var copies, an even quicker one:




                              * cw NEWNAME <esc> then repeat n. for other occurrences




                              Search for occurrence, cw is command for change word, n goes to next occurrence for last search and . repeats the last command (which is change word to NEWNAME)



                              (Credits for me knowing all this go to @doomedbunnies on Reddit)



                              Another cool trick is this: (credits to @nobe4)




                              * cgn NEWNAME <esc> then repeat . for other occurrences




                              cgn is "change whatever is the result of (find next occurrence)". Now that this is the last command, you don't need the n to go to the next occurrence, so fewer strokes again, and, more importantly, no need to alternate n and .. But, obviously, this one has the drawback of not having a way to skip an occurrence.



                              Here are some benefits:




                              • no mapping, no .vimrc(or init.vim), so you can use it in any VIM copy you come across (e.g. a quick task on some VPS or your friend's machine where configuring VIM your way would defeat the purpose of 'quick')

                              • using * or gn for word selection is very quick -- just one keystroke (well, let's say 1.5)

                              • using * or gn makes sure you don't get any matches inside other words, just as :%s/<C-R>//gc does. Beats typing the :%s/<OLDNAME>/NEWNAME/gc by hand: I personally tend to forget to use the < things to limit matches to whole words only.

                              • Not using scope will only result in a few extra strokes of n to skip unwanted matches -- probably even fewer than the extra strokes needed to limit the scope. Under normal curcumstances, your variables are most likely somewhat localized to a certain code block anyway.






                              share|improve this answer















                              I know it's an old question, and @mykola-golubyev's way obviously IS the best answer for the particular case in the OP question (which, I assume is going through obfuscated code where you're likely to have multiple blocks with same var names); but with the question name like that many people coming here from google searches probably look for a less situation-specific ways to rename variables in VIM -- and those can be more concise



                              I'm surprized no one suggested this way:




                              * :s// NEWNAME /gc




                              The * is the same as gn - it searches for the next occurence of the word under cursor AND it becomes the last searched pattern, so when you omit the search pattern in the substitute command, VIM assumes this is the pattern to search for.



                              For small amounts of var copies, an even quicker one:




                              * cw NEWNAME <esc> then repeat n. for other occurrences




                              Search for occurrence, cw is command for change word, n goes to next occurrence for last search and . repeats the last command (which is change word to NEWNAME)



                              (Credits for me knowing all this go to @doomedbunnies on Reddit)



                              Another cool trick is this: (credits to @nobe4)




                              * cgn NEWNAME <esc> then repeat . for other occurrences




                              cgn is "change whatever is the result of (find next occurrence)". Now that this is the last command, you don't need the n to go to the next occurrence, so fewer strokes again, and, more importantly, no need to alternate n and .. But, obviously, this one has the drawback of not having a way to skip an occurrence.



                              Here are some benefits:




                              • no mapping, no .vimrc(or init.vim), so you can use it in any VIM copy you come across (e.g. a quick task on some VPS or your friend's machine where configuring VIM your way would defeat the purpose of 'quick')

                              • using * or gn for word selection is very quick -- just one keystroke (well, let's say 1.5)

                              • using * or gn makes sure you don't get any matches inside other words, just as :%s/<C-R>//gc does. Beats typing the :%s/<OLDNAME>/NEWNAME/gc by hand: I personally tend to forget to use the < things to limit matches to whole words only.

                              • Not using scope will only result in a few extra strokes of n to skip unwanted matches -- probably even fewer than the extra strokes needed to limit the scope. Under normal curcumstances, your variables are most likely somewhat localized to a certain code block anyway.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Apr 16 '18 at 11:05

























                              answered Apr 16 '18 at 9:29









                              Ivan BartsovIvan Bartsov

                              12.2k44648




                              12.2k44648























                                  2














                                  You could use the 'c' modifier in the global search and replace that would ask you for confirmation for each replace. It would take longer but it might work for a non-humongous code file:



                                  %s/$var/$foo/gc


                                  The c stands for confirm.






                                  share|improve this answer


























                                  • The i stands for ignore-case. You want c, confirm every change.

                                    – Michael Kristofik
                                    Feb 28 '09 at 13:49











                                  • Not sure that you need to escape the $ of foo...

                                    – Luc M
                                    Feb 28 '09 at 14:12











                                  • oops.. sorry about that.. Fixed the answer

                                    – Adnan
                                    Feb 28 '09 at 23:19











                                  • Answer still not fixed completely ;)

                                    – user55400
                                    Mar 2 '09 at 13:40











                                  • did you mean the escaped $? That's something that's kind of a personal preference of mine. $ works without escape and also with and since in the regex world and in vi $ has special meaning, I like to escape it just for clarity.

                                    – Adnan
                                    Mar 2 '09 at 23:33
















                                  2














                                  You could use the 'c' modifier in the global search and replace that would ask you for confirmation for each replace. It would take longer but it might work for a non-humongous code file:



                                  %s/$var/$foo/gc


                                  The c stands for confirm.






                                  share|improve this answer


























                                  • The i stands for ignore-case. You want c, confirm every change.

                                    – Michael Kristofik
                                    Feb 28 '09 at 13:49











                                  • Not sure that you need to escape the $ of foo...

                                    – Luc M
                                    Feb 28 '09 at 14:12











                                  • oops.. sorry about that.. Fixed the answer

                                    – Adnan
                                    Feb 28 '09 at 23:19











                                  • Answer still not fixed completely ;)

                                    – user55400
                                    Mar 2 '09 at 13:40











                                  • did you mean the escaped $? That's something that's kind of a personal preference of mine. $ works without escape and also with and since in the regex world and in vi $ has special meaning, I like to escape it just for clarity.

                                    – Adnan
                                    Mar 2 '09 at 23:33














                                  2












                                  2








                                  2







                                  You could use the 'c' modifier in the global search and replace that would ask you for confirmation for each replace. It would take longer but it might work for a non-humongous code file:



                                  %s/$var/$foo/gc


                                  The c stands for confirm.






                                  share|improve this answer















                                  You could use the 'c' modifier in the global search and replace that would ask you for confirmation for each replace. It would take longer but it might work for a non-humongous code file:



                                  %s/$var/$foo/gc


                                  The c stands for confirm.







                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited Jan 25 '13 at 10:54









                                  Sietse van der Molen

                                  675412




                                  675412










                                  answered Feb 28 '09 at 7:35









                                  AdnanAdnan

                                  2,03342342




                                  2,03342342













                                  • The i stands for ignore-case. You want c, confirm every change.

                                    – Michael Kristofik
                                    Feb 28 '09 at 13:49











                                  • Not sure that you need to escape the $ of foo...

                                    – Luc M
                                    Feb 28 '09 at 14:12











                                  • oops.. sorry about that.. Fixed the answer

                                    – Adnan
                                    Feb 28 '09 at 23:19











                                  • Answer still not fixed completely ;)

                                    – user55400
                                    Mar 2 '09 at 13:40











                                  • did you mean the escaped $? That's something that's kind of a personal preference of mine. $ works without escape and also with and since in the regex world and in vi $ has special meaning, I like to escape it just for clarity.

                                    – Adnan
                                    Mar 2 '09 at 23:33



















                                  • The i stands for ignore-case. You want c, confirm every change.

                                    – Michael Kristofik
                                    Feb 28 '09 at 13:49











                                  • Not sure that you need to escape the $ of foo...

                                    – Luc M
                                    Feb 28 '09 at 14:12











                                  • oops.. sorry about that.. Fixed the answer

                                    – Adnan
                                    Feb 28 '09 at 23:19











                                  • Answer still not fixed completely ;)

                                    – user55400
                                    Mar 2 '09 at 13:40











                                  • did you mean the escaped $? That's something that's kind of a personal preference of mine. $ works without escape and also with and since in the regex world and in vi $ has special meaning, I like to escape it just for clarity.

                                    – Adnan
                                    Mar 2 '09 at 23:33

















                                  The i stands for ignore-case. You want c, confirm every change.

                                  – Michael Kristofik
                                  Feb 28 '09 at 13:49





                                  The i stands for ignore-case. You want c, confirm every change.

                                  – Michael Kristofik
                                  Feb 28 '09 at 13:49













                                  Not sure that you need to escape the $ of foo...

                                  – Luc M
                                  Feb 28 '09 at 14:12





                                  Not sure that you need to escape the $ of foo...

                                  – Luc M
                                  Feb 28 '09 at 14:12













                                  oops.. sorry about that.. Fixed the answer

                                  – Adnan
                                  Feb 28 '09 at 23:19





                                  oops.. sorry about that.. Fixed the answer

                                  – Adnan
                                  Feb 28 '09 at 23:19













                                  Answer still not fixed completely ;)

                                  – user55400
                                  Mar 2 '09 at 13:40





                                  Answer still not fixed completely ;)

                                  – user55400
                                  Mar 2 '09 at 13:40













                                  did you mean the escaped $? That's something that's kind of a personal preference of mine. $ works without escape and also with and since in the regex world and in vi $ has special meaning, I like to escape it just for clarity.

                                  – Adnan
                                  Mar 2 '09 at 23:33





                                  did you mean the escaped $? That's something that's kind of a personal preference of mine. $ works without escape and also with and since in the regex world and in vi $ has special meaning, I like to escape it just for clarity.

                                  – Adnan
                                  Mar 2 '09 at 23:33











                                  0














                                  In c, you may be able to make some progress using cscope. It makes an attempt at understanding syntax, so would have a chance of knowing when the letter was a variable.






                                  share|improve this answer




























                                    0














                                    In c, you may be able to make some progress using cscope. It makes an attempt at understanding syntax, so would have a chance of knowing when the letter was a variable.






                                    share|improve this answer


























                                      0












                                      0








                                      0







                                      In c, you may be able to make some progress using cscope. It makes an attempt at understanding syntax, so would have a chance of knowing when the letter was a variable.






                                      share|improve this answer













                                      In c, you may be able to make some progress using cscope. It makes an attempt at understanding syntax, so would have a chance of knowing when the letter was a variable.







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Feb 28 '09 at 12:21









                                      Kim ReeceKim Reece

                                      1,162810




                                      1,162810























                                          0














                                          If this is across multiple files, you may consider taking a look at sed. Use find to grab your files and xargs plus sed for a replace. Say you want to replace a with a_better_name in all files matching *.c, you could do



                                          find . -name "*.c" | xargs sed -i -e 's/a/a_better_name/g'



                                          Bear in mind that this will replace ALL occurrences of a, so you may want a more robust regex.






                                          share|improve this answer




























                                            0














                                            If this is across multiple files, you may consider taking a look at sed. Use find to grab your files and xargs plus sed for a replace. Say you want to replace a with a_better_name in all files matching *.c, you could do



                                            find . -name "*.c" | xargs sed -i -e 's/a/a_better_name/g'



                                            Bear in mind that this will replace ALL occurrences of a, so you may want a more robust regex.






                                            share|improve this answer


























                                              0












                                              0








                                              0







                                              If this is across multiple files, you may consider taking a look at sed. Use find to grab your files and xargs plus sed for a replace. Say you want to replace a with a_better_name in all files matching *.c, you could do



                                              find . -name "*.c" | xargs sed -i -e 's/a/a_better_name/g'



                                              Bear in mind that this will replace ALL occurrences of a, so you may want a more robust regex.






                                              share|improve this answer













                                              If this is across multiple files, you may consider taking a look at sed. Use find to grab your files and xargs plus sed for a replace. Say you want to replace a with a_better_name in all files matching *.c, you could do



                                              find . -name "*.c" | xargs sed -i -e 's/a/a_better_name/g'



                                              Bear in mind that this will replace ALL occurrences of a, so you may want a more robust regex.







                                              share|improve this answer












                                              share|improve this answer



                                              share|improve this answer










                                              answered Feb 28 '09 at 23:32









                                              Drew OlsonDrew Olson

                                              2,79631914




                                              2,79631914






























                                                  draft saved

                                                  draft discarded




















































                                                  Thanks for contributing an answer to Stack Overflow!


                                                  • Please be sure to answer the question. Provide details and share your research!

                                                  But avoid



                                                  • Asking for help, clarification, or responding to other answers.

                                                  • Making statements based on opinion; back them up with references or personal experience.


                                                  To learn more, see our tips on writing great answers.




                                                  draft saved


                                                  draft discarded














                                                  StackExchange.ready(
                                                  function () {
                                                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f597687%2fchanging-variable-names-in-vim%23new-answer', 'question_page');
                                                  }
                                                  );

                                                  Post as a guest















                                                  Required, but never shown





















































                                                  Required, but never shown














                                                  Required, but never shown












                                                  Required, but never shown







                                                  Required, but never shown

































                                                  Required, but never shown














                                                  Required, but never shown












                                                  Required, but never shown







                                                  Required, but never shown







                                                  這個網誌中的熱門文章

                                                  Academy of Television Arts & Sciences

                                                  L'Équipe

                                                  1995 France bombings