Elisp để áp dụng lệnh cho chỉ vùng đã chọn


18

Nói, tôi có một số mã như thế này:

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

Bây giờ tôi muốn some-functionchỉ hoạt động trên vùng đã chọn trong bộ đệm? Làm thế nào tôi có thể làm điều đó ? Ngoài ra, có thể có hai đường dẫn mã riêng biệt để làm một cái gì đó nếu tôi đã chọn một số khu vực và làm một cái gì đó khác nếu tôi chưa chọn.

Câu trả lời:


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

Việc sử dụng (interactive "r")có nghĩa là các tham số beginningendsẽ tự động nhận các giá trị của vùng bắt đầu và kết thúc vùng tương ứng, khi hàm được gọi. (Bạn cũng có thể nhận các giá trị đó bất cứ lúc nào bằng cách sử dụng các hàm region-beginningregion-end, tương ứng.)

Vùng luôn có mặt (nếu có một dấu trong bộ đệm hiện tại), nhưng bạn có thể không nghĩ đó là. Vùng được kích hoạt khi được tô sáng (văn bản được chọn). Bạn có thể kiểm tra xem vùng đang hoạt động bằng cách sử dụng vị ngữ region-active-p. Nhưng thử nghiệm tốt hơn thường là use-region-p, bởi vì (theo mặc định) nó chỉ trả về true (không phải nil) khi vùng này hoạt động và không trống (điểm và dấu là khác nhau).

Ban đầu, không có sự nổi bật của khu vực. Và trong một thời gian dài, mặc dù việc làm nổi bật đã có sẵn, đó không phải là hành vi mặc định. Để tô sáng xảy ra, bạn phải transient-mark-modebật (hoặc bật ít nhất là tạm thời). Theo mặc định, transient-mark-modeđược bật trong các phiên bản Emacs gần đây.

Thật hữu ích khi xem xét định nghĩa của vị ngữ use-region-p:

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

use-empty-active-regionlà một tùy chọn người dùng, có giá trị mặc định là nil(true), nghĩa là theo mặc định use-region-psẽ không trả về true nếu vùng trống. Trong trường hợp đó, để nó trở về đúng, phần cuối của vùng phải lớn hơn phần đầu (hành vi tôi đã mô tả ở trên).

Và nếu chúng ta nhìn vào định nghĩa của region-active-p:

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

Chúng tôi thấy rằng nó trả về true (không- nil) khi tất cả những điều này là đúng:

  • transient-mark-mode Được bật.
  • Dấu đang hoạt động ( mark-active).
  • Có một dấu trong bộ đệm hiện tại.

Dấu hiệu đang hoạt động thực sự là những gì khu vực đang hoạt động là tất cả về. Khi nó hoạt động, giả sử transient-mark-modelà bật và có một dấu trong bộ đệm hiện tại, vùng được tô sáng.


AFAICS nếu đánh dấu được đặt thành điểm, tức là khu vực không mở rộng, hoạt động đánh dấu là không. Vì vậy, chế độ đánh dấu hoạt động và chế độ đánh dấu tạm thời là những thứ duy nhất thêm giá trị trong các hàm khá dư thừa này.
Andreas Röhler

1
@ AndreasRöhler: Không. C-SPC M-: mark-active=> t. Bạn chắc chắn có thể có một khu vực trống vẫn đang hoạt động.
vẽ

Được rồi, cảm ơn. Vẫn nghĩ rằng mark-active và area-active-p - được xác định là mở rộng 0 - nên tất cả đều cần thiết.
Andreas Röhler
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.