Elisp для застосування команди лише до обраної області


18

Скажіть, у мене є такий код:

(defun some-function ()
  (interactive)
  ;; do something
  )

Тепер я хочу some-functionоперувати лише вибраною областю в буфері? Як я можу це зробити? Також, чи може бути два окремих кодових шляхи для того, щоб зробити щось, якщо я вибрав якусь область та щось інше, якщо я не вибрав.

Відповіді:


22
(defun some-function (beginning end)
  (interactive "r")
  (if (use-region-p)
      (message "The region is active, and is from %d to %d" beginning end)
    (message "The region is still there (from % d to %d), but it is inactive" 
             beginning end)))

Використання (interactive "r")означає, що параметри beginningі endавтоматично отримають значення регіону початку і регіону кінця відповідно, коли функція викликається. (Ви також можете отримати ці значення в будь-який час за допомогою функцій region-beginningі region-end, відповідно.)

Область завжди присутня (якщо в поточному буфері є позначка), але ви можете подумати, що це не так. Область активна, коли вона виділяється (текст вибирається). Ви можете перевірити, чи активний регіон, використовуючи предикат region-active-p. Але, як правило use-region-p, кращий тест є тим , що (за замовчуванням) він повертає справжнє (не nil) лише тоді, коли регіон є і активним, і не порожнім (точка і позначка відрізняються).

Спочатку не було виділення регіону. І тривалий час, навіть якщо підсвічування було доступне, це не поведінка за замовчуванням. Щоб підсвічування відбулося, ви повинні transient-mark-modeувімкнути (або ввімкнути принаймні тимчасово). За замовчуванням transient-mark-modeувімкнено в останніх версіях Emacs.

Корисно переглянути визначення присудка use-region-p:

(defun use-region-p ()
  (and (region-active-p)
       (or use-empty-active-region
           (> (region-end) (region-beginning)))))

use-empty-active-region- це параметр користувача, значення за замовчуванням якого nil(true), тобто за замовчуванням use-region-pне повернеться true, якщо область порожня. У цьому випадку, щоб він повернувся правдою, кінець області повинен бути більшим за початок (поведінка, яку я описав вище).

А якщо ми подивимось на визначення region-active-p:

(defun region-active-p ()
  (and transient-mark-mode
       mark-active
       (mark)))

Ми бачимо, що він повертає істину (не nil), коли все це правда:

  • transient-mark-mode увімкнено.
  • Позначка активна ( mark-active).
  • У поточному буфері є позначка.

Ознака активності - це дійсно те, про що йдеться в активному регіоні. Коли він активний, якщо припустити, що transient-mark-modeвін увімкнено і в поточному буфері є позначка, область виділяється.


AFAICS, якщо для позначки встановлено точку, тобто область не поширюється, активна марка дорівнює нулю. Тож режим маркування та режим перехідних позначок - це єдине, що додає значення в цих досить зайвих функціях.
Андреас Рёлер

1
@ AndreasRöhler: Ні. C-SPC M-: mark-active=> т. Ви точно можете мати порожній регіон, який все-таки є активним.
Дрю

Добре, дякую. І все-таки подумайте, що позначення активності та регіону-p-визначено у міру збільшення більшого нуля-- повинно бути все необхідне.
Андреас Рьолер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.