Как я могу реорганизовать исходный код C++ с помощью emacs?

Меня больше всего интересуют автоматические изменения С++ и имени метода/класса/подписи.


person Łukasz Lew    schedule 23.03.2009    source источник


Ответы (9)


Я делаю это много, поэтому я с нетерпением жду и других ответов.

Единственные трюки, которые я знаю, очень просты. Вот мои лучшие друзья в Emacs при рефакторинге кода:

M-x query-replace

Это позволяет выполнять глобальный поиск и замену. Вы будете делать это тонну, когда будете перемещать методы и часто используемые данные в другие классы или пространства имен.

C-x 3

Это дает вам отображение с двумя буферами рядом. Затем вы можете продолжить загружать в них разные файлы и перемещать курсор от одного к другому с помощью C-x o. Это довольно простой материал, но я упоминаю его из-за того, насколько мощным он делает следующий...

C-x (
(type any amount of stuff and/or emacs commands here)
C-x )

Вот как вы определяете макрос в emacs. Каждый раз, когда вам нужно делать одно и то же снова и снова с кучей кода (и это слишком сложно для запроса-замены), это спасение. Если вы ошиблись, вы можете нажать C-g, чтобы остановить определение макроса, а затем отменить (C-_), пока не вернетесь к тому, с чего начали. Ключи для вызова макроса: C-x e. Если вы хотите сделать это несколько раз, вы можете нажать Esc и сначала ввести число. Например: Esc 100 C-x e попытается вызвать ваш макрос 100 раз.

(Примечание: в Windows вы можете получить «Мета», нажав клавишу Esc или удерживая нажатой клавишу Alt).

person T.E.D.    schedule 23.03.2009
comment
Есть много других хороших инструментов. См. ответ, в котором упоминается CEDET. Кроме того, я часто использую TAGS и M-x tags-query-replace для переименования всех совпадений в поиск по тегам, который может охватывать исходные файлы. См. также M-x grep-find, который упрощает поиск всех вхождений заменяемого символа. - person slacy; 24.03.2009
comment
Я уже пробовал мутить теги. Казалось, что хлопот больше, чем оно того стоило. Возможно, во время рефакторинга оно того стоило бы? - person T.E.D.; 25.03.2009
comment
Но это не рефакторинг. Это вручную просматривает и редактирует всю вашу программу. - person vy32; 24.09.2010
comment
@ vy32 - Я согласен, что это не совсем то, о чем просил OQ. Но если вы знаете способ рефакторинга без редактирования вашей программы, я бы очень хотел услышать об этом. Возможно, для вас это премия Тьюринга... - person T.E.D.; 22.11.2010
comment
Рефакторинг отличается от редактирования программы вручную. Рефакторинг сообщает редактору, где бы вы ни увидели переменную FOO, заменить ее на BAR. Это изменит переменные FOO, а не метод, вызывающий FOO. - person vy32; 24.11.2010
comment
@ vy32 - Рефакторинг - это то, что человек делает с исходным кодом. Инструменты, конечно, помогают, но как бы ни помогали инструменты, рефакторингом занимается человек, а не инструмент. - person T.E.D.; 24.11.2010

В последних версиях Emacs (24) Semantic это умеет.

  1. Возможно активировать семантический режим M-x semantic-mode RET.
  2. Поднимите буфер Symref с помощью C-c , g.
  3. Нажмите C-c C-e, чтобы открыть все ссылки.
  4. Переименуйте с помощью R.
person muede    schedule 13.02.2014
comment
Я считаю, что это C-c , g вместо того, что у вас есть. - person lfxgroove; 09.03.2014
comment
К сожалению, для этого требуется среда POSIX. Пытаясь использовать его в MS Windows 7 (без установленных Cygwin или minGw), я получаю semantic-symref-tool-grep: Поиск программы: нет такого файла или каталога, sh после запуска C-c , g - person Jakub Narębski; 29.06.2015
comment
@JakubNarębski, возможно, вас заинтересует загрузка некоторых пакетов GnuWin32. Эти пакеты не требуют накладных расходов Cygwin или MinGW. Вы можете загрузить отдельные инструменты и поместить их каталоги bin в переменную пути. У меня все установлено в C:\Dev\Gnu32 - person Kevin Tindall; 07.08.2016
comment
Это было действительно круто, но не совсем понятно, как работает C++; похоже, предполагается, что в методе может быть не более одной переменной с именем, тогда как С++ допускает объявления переменных, например. in для инициализаторов цикла. - person kqr; 16.09.2016
comment
Великолепно! Спасибо, что поделились этим трюком, который нелегко обнаружить. - person Apteryx; 24.04.2020

Если вы умеете программировать на elisp, вы можете посмотреть на комбинацию cedet + srecode из библиотек CEDET - она ​​предоставляет все инструменты для этой задачи - найти вызывающие функции, получить сигнатуру и т.д. Но вам нужно создать инструмент рефакторинга самостоятельно, используя эти инструменты

person Alex Ott    schedule 24.03.2009
comment
Просто глядя на страницу CEDET, это кажется гораздо лучшим ответом, чем выбранный... - person Jared Oberhaus; 24.03.2009
comment
(Отредактировано для добавления ссылки на страницу CEDET). Я не уверен, что не согласен с Джаредом, но я должен попробовать. Хотя вам нужно создать инструмент рефакторинга самостоятельно, это выглядит довольно зловеще... - person T.E.D.; 25.03.2009

Что-то среднее между инструментами рефакторинга и простыми регулярными выражениями, начиная с Emacs 22, вы можете вставлять произвольные выражения elisp в замещающий текст, что позволяет выполнять невероятно мощные манипуляции с текстом. Стив Йегге написал хорошую статью о это некоторое время назад.

person jamesnvc    schedule 01.04.2009
comment
Ух ты. Это совершенно потрясающе. Я так долго пользуюсь emacs, что никогда не думал, что они его добавили. - person T.E.D.; 05.05.2009
comment
Да, но это не рефакторинг. - person vy32; 24.09.2010

Текущее (2021 г.) состояние искусства, я бы сказал, использует emacs lsp-mode с подходящим языковым сервером.

С помощью clangd или ccls, которые предоставляют протокол языкового сервера (lsp) и подключаются к lsp-mode, вы можете реорганизовать имена с помощью:

M-x lsp-переименовать

Чтобы упростить эту настройку, я бы рекомендовал использовать Spacemacs со слоями c-c++ и lsp (и использовать clangd).

person TheJJ    schedule 22.02.2015

Мой друг играл с xrefactory и сказал, что это работает очень хорошо. Хотя это недешево.

person Greg Rogers    schedule 23.03.2009
comment
Это не бесплатно и не бесплатно. :( - person ashawley; 23.03.2009
comment
Хотя это совершенно верно, ОП не просил бесплатного решения. :) При этом xrefactory не видел обновлений с 2007 года, поэтому у него могут возникнуть проблемы с рефакторингом современного C++11 и его потомков. - person mzuther; 21.02.2017
comment
Была бесплатная версия для C/Java, а также версия GPL:d, выпущенная в 2009 году. Версия под GPL все еще существует по адресу github.com/thoni56/c-xrefactory и является более полным, чем семантический рефакторинг. Но он не поддерживает C++. - person thoni56; 13.06.2018

Создайте символы cscope.

найдите символ, который вы хотите реорганизовать.

войдите в окно cscope и запустите макрос после помещения курсора в первое вхождение

  • рет
  • c-f начало вашего символа
  • перейти к началу вашего символа
  • изменить слово
  • c-x o (назад к cscope)
  • n (для следующего символа cscope)

Вы должны просто c-x c-e сейчас

person Vijayender    schedule 24.08.2012

Я полностью согласен с тем, что поиск и замена работают нормально. Тем не менее, действительно приятной особенностью cedet является 'semantic-symref-list'.

С курсором на методе запустите эту команду, и вам будет представлен буфер, в котором перечислены все места в вашем коде, которые ссылаются на этот тег.

Вы по-прежнему можете использовать трюки с поиском и заменой, и это подтвердит, что вы изменили все ссылки.

person user7957    schedule 13.12.2011

Я использовал cquery для завершения C++, в котором используется Microsoft LSP для IDE ‹-> Инструментальная связь. Сервер cquery удовлетворяет запросы протокола LSP с помощью бэкэнда clang.

lsp-emacs — это пакет, который находится между emacs и бэкендом cquery (cquery-emacs), который предоставляет функцию lsp-rename. Между прочим, как система завершения, cquery очень надежна и быстра, настоятельно рекомендуется.

Попробуйте, следуйте руководству по началу работы на cquery github: https://github.com/cquery-project/cquery/wiki/Emacs

После настройки cquery:

  1. Наведите курсор на идентификатор (класс, переменную, что угодно), который вы хотите переименовать.
  2. M-x lsp-rename
  3. Введите новое имя идентификатора.
  4. Выполните C-x s (сохраните некоторые буферы), после чего вам будет предложено сохранить все буферы, затронутые рефакторингом.

Вероятно, вам следует пройтись по всем измененным буферам и проверить, что было сделано после рефакторинга с помощью любого инструмента/языка.

person nenchev    schedule 29.03.2018
comment
Да, это современный способ в 2018 году. - person zwy; 17.09.2018