Як встановити позначку в elisp і змінити вибір?


9

Нормальна поведінка Emacs, коли активний режим перехідних знаків, полягає в тому, що коли ви здійснюєте вибір зсуву, тоді, якщо наступна команда є рухом без змін, позначка деактивується. Наприклад, після команд M-l(для позначення поточного рядка функцією нижче) та C-fпозначка деактивується. Як наслідувати цю поведінку від Elisp після (set-mark-command nil)?

Наприклад:

(defun my-mark-current-line ()
  (interactive)
  (beginning-of-line)
  (set-mark-command nil)
  (end-of-line)
  (forward-char))

(global-set-key (kbd "M-l") 'my-mark-current-line)

Тепер зробимо Ml Cf і регіон буде рости, але замість цього я хочу, щоб поведінка за замовчуванням, тобто область деактивувалась, коли Cf, та зростала разом із CSf.

EDIT : чи слід використовувати іншу функцію для встановлення-mark-command, яка дозволяє це? Я не міг знайти жодного.


Я вважаю, що це неможливо (і я можу помилитися). Поки регіон активний, навігаційні команди змінюватимуть вибір. Вибір зсуву за допомогою C-S-fаналогічний C-SPC(активація області) + C-f(навігація). Ви, ймовірно, можете отримати те, що хочете, прив’язавшись C-f до функції обгортки, яка спочатку деактивує область, якщо вона активна, а потім продовжує робити те, що C-fробить ( forward-char); і прив’язувати C-S-fбезпосередньо до forward-char. Зауважте, що якщо ви коли-небудь використовувати emacs в термінальному режимі, C-fі C-S-fобидва будуть вести себе так, C-fяк термінал не може розрізняти два.
Каушал Моді

Також обгортка та прив'язка, яку ви зробили для C-fцього, застосовуватимуться до всіх інших команд навігації, які ви також використовуєте.
Каушал Моді

btw C-fпісля M-lцього не розширює область, оскільки в кінці не існує активної області M-l(яка downcase-wordза замовчуванням пов'язана).
Каушал Моді

1
@KaushalModi Я думаю, що M-lпосилання на ОП - це не обов'язкове прив'язування ( downcase-word), а my-mark-current-line
звичайне

справді @nispio.
mikl

Відповіді:


8

Оскільки переклад зсуву та тимчасова активація знака обробляється циклом команд, вам потрібно буде викликати інтерактивні версії функцій руху, щоб отримати від них відповідне поведінку вибору зсуву:

;; (source: http://emacs.stackexchange.com/a/22166/93)
(defun my-mark-current-line ()
  (interactive)
  (beginning-of-line)
  (setq this-command-keys-shift-translated t)
  (call-interactively 'end-of-line)
  (call-interactively 'forward-char))

(global-set-key (kbd "M-l") 'my-mark-current-line)

Оновлення:

З моменту написання вищевказаної відповіді я взяв час, щоб дізнатися трохи більше про те, як насправді працює перехід змін під кришкою. Він встановлює значення символу transient-mark-modeяк комірки форми (only . OLDVAL), де OLDVALце значення до вибору зсуву.

Наведене нижче рішення дозволяє уникнути використання, call-interactivelyякщо потрібно, активуючи позначку та встановивши відповідне значення transient-mark-mode. В основному, я вважаю це рішення менш злому, ніж перше.

Як бонус, тепер він має необов'язковий підрахунок повторень і розширить поточний вибір у будь-якому напрямку, якщо позначка вже активна.

;; (source: http://emacs.stackexchange.com/a/22166/93)
(defun my-mark-current-line (&optional arg)
  "Uses shift selection to select the current line.
When there is an existing shift selection, extends the selection
in the appropriate direction to include current line."
  (interactive "p")
  (let ((oldval (or (cdr-safe transient-mark-mode) transient-mark-mode))
        (backwards (and mark-active (> (mark) (point))))
        (beg (and mark-active (mark-marker))))
    (unless beg
      (if backwards (end-of-line) (beginning-of-line))
      (setq beg (point-marker)))
    (if backwards (end-of-line (- 1 arg)) (beginning-of-line (+ 1 arg)))
    (unless mark-active
      (push-mark beg nil t))
    (setq transient-mark-mode (cons 'only oldval))))

1
Обидва працюють прекрасно, і стара справа дуже корисна! дуже дякую!
mikl
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.