Làm thế nào để thiết lập dấu trong elisp và có lựa chọn thay đổi?


9

Hành vi bình thường của Emacs khi chế độ đánh dấu tạm thời được kích hoạt là khi bạn thực hiện lựa chọn thay đổi, thì nếu lệnh tiếp theo là một chuyển động không thay đổi, nhãn hiệu sẽ bị hủy kích hoạt. Ví dụ, sau các lệnh M-l(để đánh dấu dòng hiện tại bằng hàm bên dưới) và C-f, dấu bị hủy kích hoạt. Làm thế nào để mô phỏng hành vi đó từ elisp sau (set-mark-command nil)?

Ví dụ:

(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)

Bây giờ làm Ml Cf và khu vực sẽ phát triển, nhưng thay vào đó, tôi muốn hành vi mặc định, tức là khu vực sẽ hủy kích hoạt khi Cf và phát triển với CSf.

EDIT : nên sử dụng một chức năng khác với lệnh set-mark-lệnh cho phép điều này? Tôi không thể tìm thấy bất kỳ.


Tôi tin rằng điều đó là không thể (và tôi có thể sai). Miễn là một vùng được kích hoạt, các lệnh điều hướng sẽ thay đổi lựa chọn. Lựa chọn thay đổi sử dụng C-S-ftương tự như C-SPC(kích hoạt một vùng) + C-f(điều hướng). Bạn có thể có thể có được những gì bạn muốn bằng cách liên kết C-f với một hàm bao bọc trước tiên sẽ hủy kích hoạt một vùng nếu hoạt động và sau đó tiến hành thực hiện những gì C-fdoes ( forward-char); và liên kết C-S-ftrực tiếp với forward-char. Lưu ý rằng nếu bạn từng sử dụng emacs trong chế độ thiết bị đầu cuối, C-fC-S-fcả hai sẽ hoạt động như C-fthiết bị đầu cuối không thể phân biệt giữa hai.
Kaushal Modi

Ngoài ra, trình bao bọc và ràng buộc bạn đã làm C-fsẽ áp dụng cho tất cả các lệnh điều hướng khác mà bạn sử dụng.
Kaushal Modi

btw C-fsau M-lkhông mở rộng vùng vì không có vùng hoạt động ở cuối M-l(được ràng buộc downcase-wordtheo mặc định).
Kaushal Modi

1
@KaushalModi Tôi nghĩ rằng M-lOP được gọi không phải là ràng buộc mặc định ( downcase-word), mà là ràng buộc tùy chỉnh củamy-mark-current-line
nispio

thực sự @nispio.
mikl

Câu trả lời:


8

Vì dịch chuyển ca và kích hoạt tạm thời nhãn hiệu được xử lý bởi vòng lặp lệnh, bạn sẽ cần gọi các phiên bản tương tác của các chức năng di chuyển để có được hành vi lựa chọn thay đổi phù hợp từ chúng:

;; (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)

Cập nhật:

Kể từ khi viết câu trả lời ở trên, tôi đã dành thời gian để tìm hiểu thêm một chút về cách lựa chọn ca thực sự hoạt động dưới mui xe. Nó đặt giá trị ký hiệu transient-mark-modelà một ô khuyết của biểu mẫu (only . OLDVAL), trong đó OLDVALlà giá trị trước khi chọn ca.

Giải pháp dưới đây tránh việc sử dụng call-interactivelybằng cách kích hoạt nhãn hiệu khi cần và đặt giá trị phù hợp transient-mark-mode. Về cơ bản, tôi coi giải pháp này là ít hack hơn so với giải pháp đầu tiên.

Là một phần thưởng, giờ đây nó có số lần lặp lại tùy chọn và sẽ mở rộng lựa chọn hiện tại theo một trong hai hướng nếu nhãn hiệu đã hoạt động.

;; (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
Cả hai hoạt động hoàn hảo và điều cũ là rất hữu ích! cảm ơn rất nhiều!
mikl
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.