Как заменить текущее слово под курсором в Emacs

Вопрос или проблема

Как заменить текущее слово под курсором в Emacs?

Я знаю, что могу использовать query-replace или replace-string, но каждый раз мне приходится вводить всю строку, которую нужно заменить, это просто раздражает.

В Vi есть аналогичная команда cword, и я могу использовать сочетание клавиш для подстановки слова под курсором:

nmap <leader>z :%s#\<<C-r>=expand("<cword>")<CR>\>#

Кто-нибудь знает, как сделать это в Emacs?

Инкрементальный поиск имеет эту функцию, но функции замены — нет. К счастью, инкрементальный поиск имеет способ переключения в режим замены, когда вы выбрали поисковый термин. Итак:

  • Нажмите C-s, чтобы перейти в режим инкрементального поиска
  • Нажмите C-w, чтобы добавить текущее слово в буфер поиска. Вы можете продолжать нажимать, чтобы добавлять несколько слов, а также можете использовать C-M-y для добавления отдельных символов и C-y для добавления целых строк
  • Нажмите M-%, чтобы переключиться в режим замены, используя уже созданный вами буфер поиска

Как вы, вероятно, знаете, используя M-% обычно, это режим запроса на замену, где программа спрашивает вас, что делать с каждым совпадением. Если вы просто хотите заменить их все, нажмите ! при первом совпадении.

;; query-replace current word
(defun qrc (replace-str)
   (interactive "sDo query-replace current word with: ")
   (forward-word)
   (let ((end (point)))
      (backward-word)
      (kill-ring-save (point) end)
      (query-replace (current-kill 0) replace-str) ))

Я долго мучился и хотел того же самого с момента перехода с Vim на Emacs.

После некоторых исследований и экспериментов, я придумал функцию ниже, которая позволяет сделать то же самое с установленным пакетом Evil или используя spacemacs.

Она также работает с активным регионом (или визуальным выделением в стиле vim), что может быть очень полезно для замены слова типа abc-def-hij:

; заменяет текущее слово или выделение в стиле vim для Evil-режима
(defun evil-replace-word-selection()
(interactive)
(if (use-region-p)
    (let (
            (selection (buffer-substring-no-properties (region-beginning) (region-end))))
        (if (= (length selection) 0)
        (message "empty string")
        (evil-ex (concat "'<,'>s/" selection "https://unix.stackexchange.com/"))
        ))
    (evil-ex (concat "%s/" (thing-at-point 'word) "https://unix.stackexchange.com/"))))

Затем в вашем init.el определите то же самое сочетание клавиш:

(global-set-key (kbd "\C-co") 'evil-replace-word-selection)

Сочетание клавиш немного отличается от vim, которое “space z”, но я еще не разобрался, как сопоставить это в Emacs, когда существует Evil-режим. Продолжает жаловаться, что это не префикс и т.д., и я относительно новичок в Emacs. Но все же это не так плохо, и меня устраивает это решение в данный момент.

Используйте копирование и вставку: M-d C-_ M-x replace-string RET C-y (kill-word, undo, replace-string, yank). Если вы уже начали замену, вы можете вернуться к исходному буферу, чтобы сделать копирование и вставку с помощью обычных команд переключения окна или буфера: M-x replace-string RET … C-x o M-d C-_ C-x o C-y. Вы можете использовать префиксный аргумент на M-d (например, ESC 4 2 M-d), чтобы заменить несколько слов.

Если вы планируете заменить одно или несколько слов под курсором, вы можете начать с инкрементального поиска (C-s), использовать C-w, чтобы начать поиск слова под курсором, затем нажмите M-%, чтобы переключиться на replace-string.

Если вы переходите в поиск и замену с M-S-%, то просто нажатие M-n заполняет слово под курсором, снова нажатие обертывает его в “символьный разделитель”.

Я абсолютно новичок в Emacs, но могу предложить следующее:

M-b       чтобы переместиться назад через слово
M-d       чтобы удалить до конца слова

Теперь вы можете написать новое слово. Это работает практически как cw в Vim

  1. Поместите курсор на слово, которое вы хотите заменить.
  2. Выполните
    • интерактивную функцию query-replace, используя M-x query-replace RET или M-%. Или, альтернативно,
    • интерактивную функцию query-replace-regexp, используя M-x query-replace-regexp RET или C-M-%.
  3. Нажмите стрелку вниз , чтобы слово появилось в запросе.

На это уже был дан ответ, и я не могу комментировать, потому что у меня недостаточно репутации.
Но то, что вы ищете, это ciw в Vim.

В Emacs самое близкое, что я нашел, это это сочетание:

M-b M-d

Это перемещает к началу слова, которое находится под курсором, и затем удаляет это слово.

Этот фрагмент расширяет ответ Эмануэля Берга, чтобы:

  • отобразить выбранную строку для замены;
  • использовать символ вместо слов, что дает мне лучшие результаты в коде на Python (или вообще в superword-mode).
(defun query-replace-at-point (old new)
  "Вызвать `query-replace`, присвоив OLD символу под курсором, заменив его на введенный NEW."
  (interactive
   (let* ((old-symbol (symbol-name (symbol-at-point)))
          (new-symbol (read-string (format "Переименовать %s в: " old-symbol) old-symbol)))
     (list old-symbol new-symbol)))
  (query-replace old new))

Этот подход аналогичен описанному Майклом Мрозеком, но начинается с isearch-forward-symbol-at-point, который добавляет слово в точке в поисковую строку.

  • Нажмите M-s ., чтобы перейти в режим инкрементального поиска.
  • Нажмите M-%, чтобы переключиться в режим замены.
  • Опционально нажмите M-n, чтобы предварительно заполнить строку замены поисковой строкой.

С этим подходом, курсор может находиться в любой части слова. Тестировалось, чтобы правильно работать со словами, содержащими дефисы.

.

Ответ или решение

Как заменить текущее слово под курсором в Emacs

Замена слова под курсором в Emacs может быть более эффективной, чем через стандартные команды вроде replace-string или query-replace, особенно если вы ищете функциональность, аналогичную cword в Vim. Ниже рассмотрены несколько способов, как можно осуществить замену слова под курсором в Emacs, а также предложены функции, которые позволяют облегчить этот процесс.

Использование Incremental Search и Replace

  1. Включение инкрементального поиска:

    • Нажмите C-s для перехода в режим инкрементального поиска.
    • Используйте C-w, чтобы вставить текущее слово под курсором в строку поиска. Можно повторно нажимать C-w для добавления нескольких слов, C-M-y для отдельных символов и C-y для целых строк.
  2. Переход в режим замены:

    • Нажмите M-% для перехода в режим замены, используя уже собранную строку поиска.
    • Для замены всех совпадений нажмите !.

Создание пользовательской функции для замены слова

Используйте следующую функцию, чтобы автоматически заменить текущее слово:

(defun replace-current-word (replace-str)
  "Заменяет текущее слово под курсором на вводимую строку."
  (interactive "sЗаменить текущее слово на: ")
  (forward-word)
  (let ((end (point)))
    (backward-word)
    (kill-ring-save (point) end)
    (query-replace (current-kill 0) replace-str)))

Вы можете привязать эту функцию к определенной клавише:

(global-set-key (kbd "C-c r") 'replace-current-word)

Использование Evil Mode

Если вы используете пакеты Evil или Spacemacs, вы можете применять аналогичный стиль команд, как в Vim:

(defun evil-replace-word-selection()
  (interactive)
  (if (use-region-p)
      (let ((selection (buffer-substring-no-properties (region-beginning) (region-end))))
        (unless (= (length selection) 0)
          (evil-ex (concat "'<,'>s/" selection "/РЕЗУЛЬТАТ/"))))
    (evil-ex (concat "%s/" (thing-at-point 'word) "/РЕЗУЛЬТАТ/"))))

Для активации функции:

(global-set-key (kbd "C-c o") 'evil-replace-word-selection)

Другие методы

  1. Непосредственное редактирование:

    • Используйте M-b для перемещения в начало слова.
    • Примените M-d для удаления текущего слова.
    • Введите новое слово вручную.
  2. Замена символов:

    • Используйте режим isearch-forward-symbol-at-point, нажимая M-s ., чтобы добавить слово под курсором в строку поиска.
    • Нажмите M-% для замены. Это подход особенно удобен для слов с дефисами.

Заключение

Хотя Emacs предоставляет разнообразие способов замены текста, использование пользовательских функций и навигации делает процесс более интуитивным и быстродействующим. Эти методы позволяют избежать необходимости повторного ввода искомого слова, улучшая эффективность работы с текстом.

Оцените материал
Добавить комментарий

Капча загружается...