Vim: изменить сигнатуру вызова функции через базу кода

Я медленно превращаю Vim в свою IDE по выбору, с помощью ctags и плагинов static-analysis/autocompletion/etc (например, vim-jedi, youcompleteme и т. Д.). Но я не нашел ничего, что могло бы выполнить одну конкретную задачу:

Скажем, у меня есть функция (я буду использовать Python здесь):

def my_function(outFile, foo, bar):
  outFile.write(foo[bar])

Позже я изменяю его подпись, чтобы позиционный аргумент outFile был именованным:

def my_function(foo, bar, outFile=None):
  if outFile is None:
      outFile = getDefaultOutfile()
  outFile.write(foo[bar])

Теперь я хочу изменить все старые вызовы, несмотря на всю кодовую базу:

my_function(oF, f, b)

в

my_function(f, b, outFile=oF)

Есть ли простой способ сделать это в Vim (или других утилитах Linux, например, sed)? Я знаю, что PyCharm и т.д. могут это сделать, но я пока не собираюсь прыгать с корабля.

2 ответа

Вы можете сделать это следующим образом:

:s/\vmy_function\((\w*), (\w*), (\w*)\)/my_function(\2, \3, outfile=\1)/g

Читайте о vimregex, особенно о захвате групп. В основном, что угодно (\w*) совпадения будут сохранены и названы \1 (затем \2, \3и т. д.) для использования в замен позже.

Стоит отметить, что это работает для вашего примера, но не будет работать, если есть лишние или недостающие пробелы. Чтобы сделать это более надежным, вы можете изменить его на:

:s/\vmy_function\((\w*),\s*(\w*),\s*(\w*)\)/my_function(\2, \3, outfile=\1)/g

В качестве альтернативы find (описано в предыдущем комментарии), можно также использовать grep чтобы открыть файлы, содержащие нужную функцию:

vim `grep -l 'my_function' *py`

Файлы будут загружены в разные буферы. Затем используйте общую замену буфера:

bufdo %s/\(my_function\)(.*)/\1(f, b, outFile=oF)/gc

c Флаг здесь не является обязательным, но я бы рекомендовал для этой конкретной замены.

Другие вопросы по тегам