Есть ли в emacs строки для применения к регионам? - PullRequest
8 голосов
/ 30 июня 2011

Большая часть моей работы связана с поиском и удалением ненужных строк кода.Поэтому я создаю макрос, а затем выбираю все строки (C-x h) и затем запускаю команду (apply-macro-to-region-lines).Мне удалось сохранить эту команду и поместить ее в мой файл .emacs;Я назвал это cut_it_now.Но теперь моя функция больше не является макросом, поэтому я больше не могу использовать функцию (apply-macro-to-region-lines).Знаете ли вы, если (apply-function-to-region-lines) реализовано где-то?

Большое спасибо,

D

Ответы [ 5 ]

5 голосов
/ 30 июня 2011

Обратите внимание, что вы все еще можете использовать apply-macro-to-region-lines с макросом, сгенерированным из кода, при условии макрос определен как вектор или строка.С помощью пользовательского apply-named-macro-to-region-lines [2] вы можете выбрать макрос для интерактивного использования.

Emacs может генерировать код из макроса клавиатуры двумя способами, в зависимости от метода, используемого для его присвоения имени.

Если вы используете kmacro-name-last-macro (привязано к Cx Ck n ), тогда Emacs генерирует из макроса функцию , котораянапрямую не используется для этой конкретной цели [1].

Если вы используете name-last-kbd-macro для имени вашего макроса, он будет сгенерирован как вектор или строка.

В любом случае вызатем используйте insert-kbd-macro для получения кода.

На самом деле векторный / строковый формат является форматом по умолчанию, так что вы можете пропустить шаг именования и сразу запросить код (набрав RET взапрос имени для указания последнего определенного макроса), а затем вручную отредактируйте имя по умолчанию для вставленного кода.

[1]: векторная форма, по-видимому, просто встроена в определение функции, поэтомуВы должны быть в состоянии извлечь это из кода, чтобы вручную перечитатьОпределите макрос-функцию в векторном формате.

[2]: Когда я изначально писал этот ответ, я забыл, что это была пользовательская функция.Извините за это.

(defun apply-named-macro-to-region-lines (top bottom)
  "Apply named keyboard macro to all lines in the region."
  (interactive "r")
  (let ((macro (intern
                (completing-read "kbd macro (name): "
                                 obarray
                                 (lambda (elt)
                                   (and (fboundp elt)
                                        (or (stringp (symbol-function elt))
                                            (vectorp (symbol-function elt))
                                            (get elt 'kmacro))))
                                 t))))
    (apply-macro-to-region-lines top bottom macro)))
4 голосов
/ 30 июня 2011

Следующая функция должна делать то, что вы хотите:

(defun apply-function-to-region-lines (fn)
  (interactive "aFunction to apply to lines in region: ")
  (save-excursion
    (goto-char (region-end))
    (let ((end-marker (copy-marker (point-marker)))
          next-line-marker)
      (goto-char (region-beginning))
      (if (not (bolp))
          (forward-line 1))
      (setq next-line-marker (point-marker))
      (while (< next-line-marker end-marker)
        (let ((start nil)
              (end nil))
          (goto-char next-line-marker)
          (save-excursion
            (setq start (point))
            (forward-line 1)
            (set-marker next-line-marker (point))
            (setq end (point)))
          (save-excursion
            (let ((mark-active nil))
              (narrow-to-region start end)
              (funcall fn)
              (widen)))))
      (set-marker end-marker nil)
      (set-marker next-line-marker nil))))

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

(defun test()
  (insert "> "))

И, если ваш буфер содержит следующее содержимое:

Line 1: blah, blah
Line 2: blah, blah
Line 3: blah, blah
Line 4: blah, blah

Если вы выберете область, содержащую только строки 2 и 3, введите «Mx apply-function-to-region-lines» и введите «test» в качестве имени функции при появлении запроса, вы получите следующий результат в буфере :

Line 1: blah, blah
> Line 2: blah, blah
> Line 3: blah, blah
Line 4: blah, blah
4 голосов
/ 30 июня 2011

Простое решение состоит в том, чтобы определить макрос, который вызывает вашу функцию, а затем использовать доброе старое apply-macro-to-region-lines.

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

3 голосов
/ 30 июня 2011

Я согласен с ответом @ Lindydancer, и я также добавил бы, что может быть более простой способ достичь вашей цели. например встроенная функция delete-matching-lines. : -)

0 голосов
/ 30 июня 2011

Вы всегда можете скопировать источник в apply-macro-to-region-lines и настроить его для вызова переданной функции, и, таким образом, сделать свою собственную версию.

...