Изменение имен переменных в Vim

Я пытаюсь прочитать много кода c/perl через vim, который содержит много имен переменных одной буквы.

Было бы неплохо иметь некоторую команду, которая могла бы помочь мне изменить имя переменной на что-то более значимое, пока я нахожусь в процессе чтения кода, чтобы я мог быстрее прочитать остальную часть.
Есть ли какая-то команда в vim, которая позволила бы мне быстро это сделать.

Я не думаю, что регулярные выражения будут работать cos 1) одно и то же однобуквенное имя может иметь разные цели в разных областях видимости - 2) одна и та же комбинация букв может быть частью другого более крупного имени var, или в строке или комментарии.. не хотели бы изменять эти

Любые известные решения

Ответ 1

Ниже описано, как переименовать переменную, которая определена в текущей области {}.

Переместите курсор на использование переменной. Нажмите gd. Это означает - переместите курсор в определение. Теперь нажмите [{ - это приведет вас к началу области. Нажмите V - включите выбор Visual Line. Нажмите % - перейдем к противоположному }, таким образом, выберем всю область. Нажмите :s/ - начните замену команды. <C-R>/ - вставляет шаблон, соответствующий имени переменной (это имя было нажато до нажатия gd). /newname/gc<CR> - инициирует поиск и замену с подтверждением в каждом матче.

Теперь вам нужно записать макросы или даже лучше - нанести на карту ключ.

Вот окончательные сопоставления:

" 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>

Поместите это в свой .vimrc или просто выполните. После этого нажатие gr на локальной переменной приведет вас к команде :s, где вы просто должны ввести new_variable_name и нажать Enter.

Ответ 2

AFAIK, фактическая поддержка рефакторинга в VIM отсутствует. При переименовании с целью рефакторинга я обычно принимаю следующие меры предосторожности.

  • Ограничьте область изменения моего использования меток.
  • При вводе регулярного выражения скопируйте имя с помощью \< и > . Это приведет к совпадению целого слова, которое уменьшит типы неправильных переименований, которые произойдут.
  • Не выполняйте многострочную замену, чтобы уменьшить вероятность плохой замены.
  • Внимательно просмотрите код diff, если это не что иное, как небольшое изменение.

Мое конечное изменение выглядит примерно так:

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

Я хотел бы ошибаться в том, что не существует инструмента для рефакторинга для VIM, но я его не видел.

Ответ 3

Поместите это в свой .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 Rnvar()

expand("<cword>") получает слово под курсором. Строка поиска использует % для области видимости файла, а шаблоны \(\W\) ищут символы без слов на границе слова для замены и сохраняют их в переменных \1 и \2, чтобы быть повторно - вставляется в шаблон замены.

Ответ 4

Вы можете использовать модификатор 'c' в глобальном поиске и заменить его, чтобы попросить вас подтвердить каждую замену. Это займет больше времени, но это может работать для файла с огромным кодом:

%s/\$var/\$foo/gc

С означает подтверждение.

Ответ 5

В c, вы можете сделать некоторый прогресс, используя cscope. Он пытается понять синтаксис, поэтому у него будет возможность узнать, когда буква была переменной.

Ответ 6

Если это относится к нескольким файлам, вы можете рассмотреть возможность поиска sed. Используйте find, чтобы захватить ваши файлы и xargs plus sed для замены. Предположим, вы хотите заменить a на имя a_better_имя во всех файлах, соответствующих *.c, вы могли бы сделать

найти. -name "*.c" | xargs sed -i -e 's/a/a_better_name/g'

Имейте в виду, что это заменит ВСЕ вхождения a, поэтому вам может понадобиться более надежное регулярное выражение.