Как искать и заменять во всем буфере?


17

Поиск и замена с помощью M-%и !выполняется с текущей позиции до конца буфера. Как я могу сделать это для всего буфера? Благодарю.


2
Я предлагаю изменить название на «поиск и замена всего буфера». Глобально может также относиться ко всем проектам.
Малабарба

1
Это одна из областей, где Vim / Evil трудно победить::%s/foo/bar
shosti

@shosti: На самом деле, я думаю, что ваш метод требует больше нажатий клавиш. Просто
скажи

Ответы:


14

Я не вижу, чтобы это поддерживалось, сохраняя при этом вашу стартовую позицию. (Я не вижу способа переноса в начало буфера, когда поиск достигает конца.)

Лучше всего использовать M-<для перехода в начало буфера, а затем query-replace, когда вы закончите, нажмите, C-uC-spaceC-uC-spaceчтобы вернуться к исходной точке.


1
Это работает, когда transient-mark-modeвключен. В противном случае C-SPC C-SPCбудет временно transient-mark-mode
включен

5
Нет необходимости устанавливать отметку вручную с помощью C-SPC. M- <(и многие другие команды, которые потенциально «перемещают точку на долгий путь») делают это за вас.
Матиас Даль

9

Вы можете добавить следующую команду в ваш файл инициализации emacs и связать ее с выбранной клавишей.

(defun replace-regexp-entire-buffer (pattern replacement)
  "Perform regular-expression replacement throughout buffer."
  (interactive
   (let ((args (query-replace-read-args "Replace" t)))
     (setcdr (cdr args) nil)    ; remove third value returned from query---args
     args))
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward pattern nil t)
      (replace-match replacement))))

9

Вы можете выполнить следующие шаги:

  • C-x h- Выберите весь буфер или M-< - Перейти к верхней части буфера
  • M-% - Положить начало query-replace
  • ! - силой заменить все
  • C-u C-SPC C-u C-SPC - Вернитесь в исходное положение

Это должно привлечь больше внимания.
Индра

3

Вы можете добавить это в свой init.elфайл, чтобы обновить поведение M-%для замены слова во всем буфере по умолчанию:

(defun my/query-replace (from-string to-string &optional delimited start end)
  "Replace some occurrences of FROM-STRING with TO-STRING.  As each match is
found, the user must type a character saying what to do with it. This is a
modified version of the standard `query-replace' function in `replace.el',
This modified version defaults to operating on the entire buffer instead of
working only from POINT to the end of the buffer. For more information, see
the documentation of `query-replace'"
  (interactive
   (let ((common
      (query-replace-read-args
       (concat "Query replace"
           (if current-prefix-arg " word" "")
           (if (and transient-mark-mode mark-active) " in region" ""))
       nil)))
     (list (nth 0 common) (nth 1 common) (nth 2 common)
       (if (and transient-mark-mode mark-active)
           (region-beginning)
         (buffer-end -1))
       (if (and transient-mark-mode mark-active)
           (region-end)
         (buffer-end 1)))))
  (perform-replace from-string to-string t nil delimited nil nil start end))
;; Replace the default key mapping
(define-key esc-map "%" 'my/query-replace)

И получить такое же поведение от query-replace-regexp:

(defun my/query-replace-regexp (regexp to-string &optional delimited start end)
  "Replace some things after point matching REGEXP with TO-STRING.  As each
match is found, the user must type a character saying what to do with
it. This is a modified version of the standard `query-replace-regexp'
function in `replace.el', This modified version defaults to operating on the
entire buffer instead of working only from POINT to the end of the
buffer. For more information, see the documentation of `query-replace-regexp'"
  (interactive
   (let ((common
      (query-replace-read-args
       (concat "Query replace"
           (if current-prefix-arg " word" "")
           " regexp"
           (if (and transient-mark-mode mark-active) " in region" ""))
       t)))
     (list (nth 0 common) (nth 1 common) (nth 2 common)
       (if (and transient-mark-mode mark-active)
           (region-beginning)
         (buffer-end -1))
       (if (and transient-mark-mode mark-active)
           (region-end)
         (buffer-end 1)))))
  (perform-replace regexp to-string t t delimited nil nil start end))
;; Replace the default key mapping
(define-key esc-map [?\C-%] 'my/query-replace-regexp)

Очень полезный. Благодарю.
NVaughan

2

Если вы используете Icicles, вы можете искать и заменять весь буфер (или несколько буферов, файлов или закладок).

И в отличие query-replace(например C-x h M-%):

  • Вы можете перемещаться по матчам в любом порядке .

  • Замена по требованию: вам не нужно посещать каждый матч и отвечать, стоит ли его заменять.


0

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

(defun query-replace-from-top ()
  (interactive)
  (let ((orig-point (point)))
    (save-excursion
      (goto-char (point-min))
      (call-interactively 'query-replace))
    (message "Back to old point.")
    (goto-char orig-point)))
(bind-key* "M-%" 'query-replace-from-top)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.